使用python爬蟲爬取百度手機助手網站中app的資料
阿新 • • 發佈:2019-02-16
一、爬取程式流程圖
爬蟲程式流程圖如下:
二、具體步驟
1.分析url地址結構
進入百度手機助手網站http://shouji.baidu.com/software/後,可以看到共分為十個類別:社交通訊、系統工具、理財購物等等,可以知道通過這十個類別分別爬取app的資料,應該就可以全部完整的爬取到所有app。
隨意點選一個類別進入後,如點選社交通訊這一大類,看到url是:http://shouji.baidu.com/software/503/
每個類別頁都有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陣列中。
#爬取所有應用 詳情 頁的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
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檔案中。
#將資料儲存到json
def 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 urllib2
import re
import json
class 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()