使用python爬虫爬取百度手机助手网站中app的数据

来源:互联网 发布:淘宝低价销售的危害 编辑:程序博客网 时间:2024/05/01 08:43

基于python2.7版本,爬取百度手机助手(http://shouji.baidu.com/software/)网站中app的数据。

一、爬取程序流程图

爬虫程序流程图如下:

Created with Raphaël 2.1.0开始分析地址结构获得app类别页的url爬取app详情页url爬取App详情页的数据将爬取数据保存到json文件结束

二、具体步骤

1.分析url地址结构

进入百度手机助手网站http://shouji.baidu.com/software/后,可以看到共分为十个类别:社交通讯、系统工具、理财购物等等,可以知道通过这十个类别分别爬取app的数据,应该就可以全部完整的爬取到所有app。
随意点击一个类别进入后,如点击社交通讯这一大类,看到url是:http://shouji.baidu.com/software/503/,分析可以知道这十个类别分别是501~510,即url就是shouji.baidu.com/software/再加上501~510中的一个数字。
每个类别页都有1-8页不等的app,比如社交通讯类app的第二页就是http://shouji.baidu.com/software/503/list_2.html,也就是在list_后面加上数字1-8即可。
经过以上的分析,可以将爬取的url分为以下的三部分结构:

self.base_URL = 'http://shouji.baidu.com/software/'self.category_num = [501, 502, 503, 504, 505, 506, 507, 508, 509, 510]self.page_num = [1, 2, 3, 4, 5, 6, 7, 8]

其中category_num和page_num分别代表类别数字和分页编号。

2.获得所有app类别页的url

定义数组categoryPageURL_list进行类别页拼接后url的储存:

def getAppCategoryPageURL(self):        #所有应用类别的URLlist        categoryPageURL_list = []        for x in self.category_num:            for y in self.page_num:                categoryPageURL_list.append(self.base_URL + str(x) + '/list_' + str(y) + '.html')        return categoryPageURL_list

3.爬取所有app详情页的url

进行所有app详情页url 的爬取,并将其储存在appDetailPageURL_list数组中。

#爬取所有应用 详情 页的urldef getAppDetailPageURL(self):    categoryPageURL_list = self.getAppCategoryPageURL()    appDetailPageURL_list = []    for url in categoryPageURL_list:        #构造request请求对象        request = urllib2.Request(url)        response = urllib2.urlopen(request)        content = response.read().decode("unicode-escape")        #re模块用于对正则表达式的支持,pattern可以理解为一个匹配模式,re.S指"."可以匹配换行"\n"        pattern = re.compile('<div.*?app-box">.*?<a href="(.*?)".*?>', re.S)        resultStr = re.findall(pattern, content)        for result in resultStr:            #print 'crawling ' + result            appDetailPageURL = 'http://shouji.baidu.com/' + result            appDetailPageURL_list.append(appDetailPageURL)    return appDetailPageURL_list

4.爬取App详情页的数据

对App详情页的内容进行爬取,得到app的具体数据。

#爬取App详情页中的所需内容def getAppInfo(self, appURL):   try:       request = urllib2.Request(appURL)       response = urllib2.urlopen(request)   except urllib2.URLError, e:       print "Get appInfo failed:", e.reason       return None   content = response.read().decode("utf-8")   # 创建保存结果的dict   result = {}   #得到app名字   pattern = re.compile('<span>(.*?)</span>')   resultStr = re.search(pattern, content)   if resultStr:       result['Name'] = resultStr.group(1)   # 得到app大小,需要对字符串处理   pattern = re.compile('<span class="size">(.*?)</span>')   resultStr = re.search(pattern, content)   if resultStr:       result['Size'] = (((resultStr.group(1)).split(':'))[1]).strip()   #版本   pattern = re.compile('<span class="version">(.*?)</span>')   resultStr = re.search(pattern, content)   if resultStr:       result['Version'] = (((resultStr.group(1)).split(':'))[1]).strip()   #下载量   pattern = re.compile('<span class="download-num">(.*?)</span>')   resultStr = re.search(pattern, content)   if resultStr:       result['download-num'] = (((resultStr.group(1)).split(':'))[1]).strip()   #LOGO URL   pattern = re.compile('<img src="(.*?)".*?/>')   resultStr = re.search(pattern, content)   if resultStr:       result['app-pic'] = resultStr.group(1)   #下载地址   pattern = re.compile('<div.*?area-download">.*?<a target="_blank.*?href="(.*?)".*?>', re.S)   resultStr = re.search(pattern, content)   if resultStr:       result['app-href'] = resultStr.group(1)   #详情页   result['page-url'] = appURL   #应用描述   pattern = re.compile('<p.*?content content_hover">(.*?)<span.*?>.*?</span></p>', re.S)   resultStr = re.search(pattern, content)   if resultStr:       result['description'] = resultStr.group(1)   else:       pattern = re.compile('<div class=.*?brief-long">.*?<p.*?content">(.*?)</p>.*?</div>', re.S)       resultStr = re.search(pattern, content)       if resultStr:           result['description'] = resultStr.group(1)   #应用截图   pattern = re.compile('<li><img data-default=.*?src="(.*?)".*?>', re.S)   resultStr = re.search(pattern, content)   if resultStr:       result['screen-shot'] = resultStr.group(1)   #print result   return result

5.将爬取数据保存到json文件

在此方法中将所有爬取的数据保存到appData.json文件中。

#将数据保存到jsondef saveData(self, resultInfo):     # resultInfo转换为json数据格式进行保存     encodedjson = json.dumps(resultInfo)     with open('appData.json', 'w') as f:         f.write(encodedjson)     print 'Finished.'

我将所有的方法及参数封装到Spider类中,建立爬虫的开始入口,整体代码如下:

# -*- coding:utf-8 -*-import urllib2import reimport jsonclass AppSipder:    def __init__(self):        #URL模式:http://shouji.baidu.com/software/502/list_x.html,分成三个部分        self.base_URL = 'http://shouji.baidu.com/software/'        #类别数字        #self.category_num = [501, 502, 503, 504, 505, 506, 507, 508, 509, 510]        self.category_num = [501]        #分页编号        #self.page_num = [1, 2, 3, 4, 5, 6, 7, 8]        self.page_num = [1]    #获得所有应用 类别 页的url    def getAppCategoryPageURL(self):        #所有应用类别的URLlist        categoryPageURL_list = []        for x in self.category_num:            for y in self.page_num:                categoryPageURL_list.append(self.base_URL + str(x) + '/list_' + str(y) + '.html')        return categoryPageURL_list    #爬取所有应用 详情 页的url    def getAppDetailPageURL(self):        categoryPageURL_list = self.getAppCategoryPageURL()        appDetailPageURL_list = []        for url in categoryPageURL_list:            #构造request请求对象            request = urllib2.Request(url)            response = urllib2.urlopen(request)            content = response.read().decode("unicode-escape")            #re模块用于对正则表达式的支持,pattern可以理解为一个匹配模式,re.S指"."可以匹配换行"\n"            pattern = re.compile('<div.*?app-box">.*?<a href="(.*?)".*?>', re.S)            resultStr = re.findall(pattern, content)            for result in resultStr:                #print 'crawling ' + result                appDetailPageURL = 'http://shouji.baidu.com/' + result                appDetailPageURL_list.append(appDetailPageURL)        return appDetailPageURL_list    #爬取App详情页中的所需内容    def getAppInfo(self, appURL):        try:            request = urllib2.Request(appURL)            response = urllib2.urlopen(request)        except urllib2.URLError, e:            print "Get appInfo failed:", e.reason            return None        content = response.read().decode("utf-8")        # 创建保存结果的dict        result = {}        #得到app名字        pattern = re.compile('<span>(.*?)</span>')        resultStr = re.search(pattern, content)        if resultStr:            result['Name'] = resultStr.group(1)        # 得到app大小,需要对字符串处理        pattern = re.compile('<span class="size">(.*?)</span>')        resultStr = re.search(pattern, content)        if resultStr:            result['Size'] = (((resultStr.group(1)).split(':'))[1]).strip()        #版本        pattern = re.compile('<span class="version">(.*?)</span>')        resultStr = re.search(pattern, content)        if resultStr:            result['Version'] = (((resultStr.group(1)).split(':'))[1]).strip()        #下载量        pattern = re.compile('<span class="download-num">(.*?)</span>')        resultStr = re.search(pattern, content)        if resultStr:            result['download-num'] = (((resultStr.group(1)).split(':'))[1]).strip()        #LOGO URL        pattern = re.compile('<img src="(.*?)".*?/>')        resultStr = re.search(pattern, content)        if resultStr:            result['app-pic'] = resultStr.group(1)        #下载地址        pattern = re.compile('<div.*?area-download">.*?<a target="_blank.*?href="(.*?)".*?>', re.S)        resultStr = re.search(pattern, content)        if resultStr:            result['app-href'] = resultStr.group(1)        #详情页        result['page-url'] = appURL        #应用描述        pattern = re.compile('<p.*?content content_hover">(.*?)<span.*?>.*?</span></p>', re.S)        resultStr = re.search(pattern, content)        if resultStr:            result['description'] = resultStr.group(1)        else:            pattern = re.compile('<div class=.*?brief-long">.*?<p.*?content">(.*?)</p>.*?</div>', re.S)            resultStr = re.search(pattern, content)            if resultStr:                result['description'] = resultStr.group(1)        #应用截图        pattern = re.compile('<li><img data-default=.*?src="(.*?)".*?>', re.S)        resultStr = re.search(pattern, content)        if resultStr:            result['screen-shot'] = resultStr.group(1)        #print result        return result    #爬虫开始入口    def startSpider(self):        print 'Start crawling please wait...'        appDetailPageURL_list = self.getAppDetailPageURL()        resultInfo = []        for url in appDetailPageURL_list:            resultInfo.append(self.getAppInfo(url))        print len(resultInfo), 'apps have been crawled.'        #resultInfo转换为json数据格式进行保存        encodedjson = json.dumps(resultInfo)        with open('appData.json', 'w') as f:            f.write(encodedjson)        print 'Finished.'Spider = AppSipder()Spider.startSpider()
4 0