爬取appstore应用信息

#!/usr/bin/env python
# encoding=utf8  
import sys  

import bs4
from bs4 import BeautifulSoup
import requests
import json
import re

gIgnoreGenreList = ['报刊杂志', '贴纸', '商品指南']
    
# https://www.apple.com/cn/itunes/charts/paid-apps/
# https://www.apple.com/cn/itunes/charts/free-apps/
def parse_appstore_page(cate_url, out_file):
    # section apps grid
    html = requests.get(cate_url).content  
    soup = BeautifulSoup(html, 'html.parser', from_encoding='utf-8')

    result = soup.find("div", id="main")

    result = result.find("section", class_="section apps grid")
    result = result.find("ul")
    app_list = result.children
    app_result = []
    for child in app_list:
        if isinstance(child, bs4.element.Tag):
            app_info = child.find("h3").find("a")

            # print child
            app_name = app_info.string
            app_itunes_url = app_info.get("href")

            # print(repr(app_name).decode('unicode-escape'))
            # print(repr(app_detail_url).decode('unicode-escape'))
            one_app = {}
            one_app["app_name"] = app_name
            one_app["app_detail_url"] = app_itunes_url
            app_result.append(one_app)

    if len(out_file) > 0:
        print "save result to file :%s" % out_file
        result_string = json.dumps(app_result, ensure_ascii=False)
        f=open(out_file,"w")
        f.write(result_string)
        f.write('\n')
        f.close()

# https://itunes.apple.com/cn/genre/ios/id36?mt=8
def parse_genre_page(genre_url, limit = 10, out_file = "genre_result.txt"):
    html = requests.get(genre_url).content  
    soup = BeautifulSoup(html, 'html.parser', from_encoding='utf-8')

    result = soup.find("div", id="main")

    result = result.find("div", id="content")
    result = result.find("div", id="genre-nav")
    result = result.find("div", class_="grid3-column")

    # ul list
    ul_list = result.find_all("ul", recursive=False)
    cate_result = []

    for one_ul in ul_list:
        if isinstance(one_ul, bs4.element.Tag):

            cate_list = one_ul.children

            for cate in cate_list:
                cate_info = cate.find("a")
                cate_name = cate_info.string

                if cate_name in gIgnoreGenreList:
                    print "ingore cate :" + cate_name
                    continue

                cate_url = cate_info.get("href")

                one_cate = {}
                one_cate["name"] = cate_name
                one_cate["url"] = cate_url

                print "processing genre %s." % cate_name
                cate_app = parse_genre_content(cate_url, limit)
                one_cate["app_list"] = cate_app

                cate_result.append(one_cate)
                break

    if len(out_file) > 0:
        print "save result to file :%s" % out_file
        result_string = json.dumps(cate_result, ensure_ascii=False)
        f=open(out_file,"w")
        f.write(result_string)
        f.write('\n')
        f.close()

# https://itunes.apple.com/cn/genre/ios-导航/id6010?mt=8 
# 返回一个数组 [{app_name:xxxx, app_detail_url:xxxxx}]
# limit 为app返回数量,-1 为不限制
def parse_genre_content(content_url, limit = -1):
    html = requests.get(content_url).content  
    soup = BeautifulSoup(html, 'html.parser', from_encoding='utf-8')

    result = soup.find("div", id="main")

    result = result.find("div", id="content")
    result = result.find("div", id="selectedgenre")
    result = result.find("div", class_="grid3-column")

    # ul list
    ul_list = result.find_all("div")
    app_result = []

    count = 0
    for one_ul in ul_list:
        if isinstance(one_ul, bs4.element.Tag):

            app_list = one_ul.find("ul").children

            for app in app_list:
                if isinstance(app, bs4.element.Tag):
                    

                    if limit > -1 and count >= limit:
                        break   
                    # print count
                    app_info = app.find("a")
                    app_name = app_info.string
                    app_url = app_info.get("href")

                    one_app = {}
                    one_app["app_name"] = app_name
                    one_app["app_detail_url"] = app_url
                    one_app["app_id"] = parse_appid(app_url)

                    app_detail = parse_detail_page(app_url)

                    if app_detail != None:
                        print app_detail
                        one_app.update(app_detail)
                    
                    app_result.append(one_app)
                    count += 1
                        
    return app_result


# https://itunes.apple.com/cn/app/高德地图-精准导航-出行必备/id461703208?mt=8
# {latest_version:x.x.x, update_date:xxxxxxx, system_version:iOS 7.0}
def parse_detail_page(detail_url):
    app_detail = {}

    html = requests.get(detail_url).content  
    soup = BeautifulSoup(html, 'html.parser', from_encoding='utf-8')
    result = soup.find("main", class_="is-app-theme")

    # print result
    # result_string = soup
    # f=open("out_file.txt","w")
    # print >> f, result
    # f.write(result_string)
    # f.close()

    # return

    whats_new = result.find("section", class_="l-content-width section section--bordered whats-new")

# 获取版本号和最后更新时间
    update_date = whats_new.find("time").string
    latest_version = parse_appver(whats_new.find("p").string)

    # print update_date
    # print latest_version
    # APP 信息
    information = result.find("dl", class_=["information-list", "information-list--app", "medium-columns"])

# 获取app支持的最低iOS系统版本号
    version_label = information.select("div")[3].select("div > span")[0].string
    system_version = parse_systver(version_label)
    
    # print system_version
    # return

    app_detail["update_date"] = update_date
    app_detail["latest_version"] = latest_version
    app_detail["system_version"] = system_version
    
    return app_detail

def parse_appid(detail_url):
    # [^/]+(?!.*/)(?=[\?]+)
    return re.search("[^/]+(?!.*/)(?=[\?]+)", detail_url).group(0)

def parse_systver(version_label):
    # return version_label
    return re.search("iOS.(\d+\.\d+)", version_label).group(1)

def parse_appver(version_label):
    # "版本 10.5.0"
    # return version_label
    return re.search(u"版本\s(.+)", version_label).group(1)

if __name__ == '__main__':

    reload(sys)  
    sys.setdefaultencoding('utf8')   
    # parse_appstore_page('https://www.apple.com/cn/itunes/charts/free-apps/', 'free-apps.txt')
    # parse_appstore_page('https://www.apple.com/cn/itunes/charts/paid-apps/', 'paid-apps.txt')

    parse_genre_page('https://itunes.apple.com/cn/genre/ios/id36?mt=8', 1, 'appstore-genre.txt')

    # version = re.search("iOS.(\d+\.\d+)", "xxx iOS 8.0 asdasdadasd").group(1)
    # print version

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335