Mac環境Python配置
安轉最新版 Python 3.6.4:Mac OS X 64-bit/32-bit installer
安裝最新Mac版 PyCharm 2017.3.3
打開PyCharm,新建Project,新建Python File
點擊File/ Default Settings/ Project Interpreter/ 選擇你當前的項目,然後選擇”+”號(Install)
搜索並安裝用於網頁解析庫BeautifulSoup的bs4和beautifulsoup4、HTTP庫requests、網頁解析庫lxml以及用於正則表達式的re,關於正則表達式入門可以參考唯心不易博主的『Python 正則表達式入門(初級篇)』
應用搜索
使用Chrome瀏覽器打開安卓應用市場頁面,這裏用百度手機助手舉例,搜索欄中輸入目標應用關鍵詞,如『123』。
跳轉後觀察地址欄:
http://shouji.baidu.com/s?wd=123&data_type=app&f=header_software%40input,其實我們只需要http://shouji.baidu.com/s?wd=123,而末尾的『123』就是剛纔搜索的關鍵詞。
若只更改『123』爲『CSDN』,頁面就會跳轉到『CSDN』的搜索結果:http://shouji.baidu.com/s?wd=CSDN,所以通過修改 = 號後面的變量(部分網站是 search/ 或 app/ ),我們可以快速獲取相關搜索頁面,這個變量我們取名爲AppName。
最終,我們的搜索網址searchUrl爲固定值http://shouji.baidu.com/s?wd= + AppName。部分網站鏈接稍微複雜,多搜索幾次,找到不變的部分,修改剩餘部分即可。
有了網址和關鍵詞,我們可以初步編寫腳本實現搜索功能:
#引入相關庫
from bs4 import BeautifulSoup
import requests
import re
# 手動爬蟲方法
def ManualCrawl():
# 交互式輸入應用名作爲參數
appName = input("please print app's name:")
# 輸入完成後執行方法
CaculateDownloadTimes(appName)
# 傳入搜索應用名
def CaculateDownloadTimes(AppName):
# 完整的搜索鏈接
searchUrl = 'http://shouji.baidu.com/s?wd=' + AppName
# 獲取網頁html碼
htmlData = requests.get(searchUrl)
# 解析網頁
soup = BeautifulSoup(htmlData.text, 'lxml')
信息提取
搜索結果有了,怎麼對結果進行分析呢?右擊頁面,點擊『檢查』,網頁會出現一片區域(即上文註釋中的html代碼),像這樣:
鼠標在紅框區域內上下移動,可以發現左邊會根據鼠標懸浮位置不同,高亮不同區域。我們找到第一個應用『CSDN』的名字所對應的html代碼塊:
右擊代碼塊 -> Copy -> Copy selector,可以得到應用名在html中的路徑:”#doc > div.yui3-g > div > div > ul > li:nth-child(1) > div > div.info > div.top > a”,通過select方法我們可以得到第一個搜索結果的應用名firstRecordName :
firstRecordName = soup.select(
'body > div:nth-of-type(2) > div:nth-of-type(2) > div > div > ul > li:nth-of-type(1) > div > div:nth-of-type(2) > div:nth-of-type(1)')[
0].get_text().encode('latin1').decode('utf-8').strip()
print('firstRecordName: ' + firstRecordName)
有以下幾點需要注意:
- nth-child 要替換成 nth-of-type;
- 可以發現路徑不盡相同,因爲完全用 Copy selector 的路徑可能會發生莫名的錯誤,這時候就需要手寫路徑:一般從 body 開始,然後若< a b >內的前半段a唯一,則直接寫a即可;若不唯一,要寫出其序列n,從1開始: a:nth-of-type(n);
- get_text方法是將select的soup[0]轉換成str格式,有些網站需要先用 latin1 編碼,再用 utf-8 解碼才能正常顯示。
示例代碼
from bs4 import BeautifulSoup
import requests
import re
# 網上說可以繞過反爬蟲,但是加了沒啥效果,應用寶依舊顯示無相關搜索內容
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko)'}
# 傳入安卓市場名、搜索應用名
def DownloadTimes(MarketName, AppName):
# 木螞蟻
if MarketName == 'mumayi' or MarketName == '木螞蟻' or MarketName == 'ant':
searchUrl = 'http://s.mumayi.com/index.php?q=' + AppName
# 獲取網頁源碼
htmlData = requests.get(searchUrl, headers=headers)
# print('content:' + htmlData.text)
# 解析網頁
soup = BeautifulSoup(htmlData.text, 'lxml')
# 獲取應用名字
try:
firstRecordName = soup.select(
'#allbody > div.main960.pos_rel > div.w670.fl > div:nth-of-type(2) > ul.applist > li:nth-of-type(1) > h3 > a:nth-of-type(1)')[
0].get_text().strip().split()[0]
# print('firstRecordName: ' + firstRecordName)
# 獲取下載量
try:
times = soup.select(
'#allbody > div.main960.pos_rel > div.w670.fl > div:nth-of-type(2) > ul.applist > li:nth-of-type(1) > a.agray > ul > li.num')[
0].get_text()[5:-1] #[x:-y]表示: 切除掉從左往右x個字符,同時切除掉從右往左y個字符
print("'" + firstRecordName + "'" + "在'木螞蟻'的下載量: " + times)
except:
print(MarketName + ' search error')
except:
print("在'木螞蟻'中未找到與'" + AppName + "'相關的內容")
# *****************需要在獲取下載量之前判斷搜索結果*****************
# 樂商店
elif MarketName == 'lenovomm' or MarketName == '樂商店' or MarketName == 'le':
searchUrl = 'http://www.lenovomm.com/search/index.html?q=' + AppName
# 獲取網頁源碼
htmlData = requests.get(searchUrl, headers=headers, verify=False)
# print('content:' + htmlData.text)
# 解析網頁
soup = BeautifulSoup(htmlData.text, 'lxml')
try:
# 獲取第一個搜索內容的名字
tip = soup.select('body > div.w1000.bcenter > p')[0].get_text()
# print(tip)
if tip == '抱歉,沒有找到相關應用。':
print("'樂商店'沒有找到相關應用")
# 終止程序
quit()
firstRecordName = soup.select(
'body > div.w1000.bcenter > div.border1.h-100.boxShadow.fl.searchAppsBox > ul > li:nth-of-type(1) > div.appDetails > p.f16.ff-wryh.appName > a')[
0].get_text().strip()
# print(firstRecordName)
# 獲取下載量
try:
times = soup.select(
'body > div.w1000.bcenter > div.border1.h-100.boxShadow.fl.searchAppsBox > ul > li:nth-of-type(1) > div.appInfo.tcenter.pr > p:nth-of-type(1) > span')[
0].get_text()[:-3]
print("'" + firstRecordName + "'" + "在'樂商店'的下載量: " + times)
except:
print(MarketName + ' search error')
except:
print("在'樂商店'中未找到與'" + AppName + "'相關的內容")
# *******************需要latin1、utf-8解碼*******************
# 智匯雲
elif MarketName == 'zhihuiyun' or MarketName == '智匯雲' or MarketName == 'huawei':
searchUrl = 'http://app.hicloud.com/search/' + AppName
# 獲取網頁源碼
htmlData = requests.get(searchUrl, headers=headers)
# 解析網頁
soup = BeautifulSoup(htmlData.text, 'lxml')
# 獲取第一個搜索內容的名字
try:
firstRecordName = soup.select(
'body > div.lay-body > div.lay-main > div.lay-left.corner > div > div > div:nth-of-type(2) > div.game-info.whole > h4 > a')[
0].get_text().encode('latin1').decode('utf-8').strip()
# print(firstRecordName)
try:
times = soup.select(
'body > div.lay-body > div.lay-main > div.lay-left.corner > div > div > div:nth-of-type(2) > div.game-info.whole > div.app-btn > span')[
0].get_text().encode('latin1').decode('utf-8')
times = times.split('次')[0].split(':')[1]
print("'" + firstRecordName + "'" + "在'智匯雲'的下載量: " + times)
except:
print(MarketName + ' search error')
except:
print("在'智匯雲'中未找到與'" + AppName + "'相關的內容")
# ********************需要跳轉2級頁面獲取下載量********************
# 當貝
elif MarketName == 'dangbei' or MarketName == '當貝':
searchUrl = 'http://www.dangbei.com/app/plus/search.php?kwtype=0&q=' + AppName
# 獲取網頁源碼
htmlData = requests.get(searchUrl, headers=headers)
# print('content:' + htmlData.text)
# 解析網頁
soup = BeautifulSoup(htmlData.text, 'lxml')
try:
# 獲取第一個搜索內容的名字
firstRecordName = soup.select('#softList > li:nth-of-type(1) > div > div.softInfo > p.title > a')[
0].get_text().strip()
# 正則表達式找出擡頭與紅色關鍵詞之間的跳轉鏈接文本
# 正則表達式的運用可以參考這篇博客: https://www.cnblogs.com/chuxiuhong/p/5885073.html
pattern0 = re.compile(r'<a href=".+' + "<font color='red'>")
linkUrls = pattern0.findall(htmlData.text)
# print(linkUrls[0])
# 獲取二級頁面鏈接
linkUrl = 'http://www.dangbei.com' + linkUrls[0].split()[1].split('"')[1]
# print(linkUrl)
# 進入二級頁面,以獲取下載量
htmlData = requests.get(linkUrl, headers=headers)
soup = BeautifulSoup(htmlData.text, 'lxml')
# 獲取下載量
try:
times = soup.select(
'#softAbs > div.info > p:nth-of-type(4) > span.lInfo')[
0].get_text().encode('latin1').decode('utf-8').strip()
times = times.split(':')[1]
print("'" + firstRecordName + "'" + "在'當貝'的下載量:" + times)
except:
print(MarketName + ' search error')
except:
print("在'當貝'中未找到與'" + AppName + "'相關的內容")
# 輸入有誤,重新輸入市場名
else:
print("input market's name error")
ManualCrawl()
# 手動輸入
def ManualCrawl():
marketName = input("please print market's name:")
appName = input("please print app's name:")
# 輸入完成後執行方法
DownloadTimes(marketName, appName)
# 各類數組
marketsArr = ['木螞蟻', '樂商店', '智匯雲', '當貝']
appsArr = ['A', '天', '3', '心']
exampleAppName = ['QQ', '微信', '王者榮耀', '抖音', '愛奇藝', '優酷']
# 自動檢測, 以市場區分
def AutoCrawlUponMarkets():
# 設置計數器
count = 0
for marketName in marketsArr:
for appName in appsArr:
count = count + 1
DownloadTimes(marketName, appName)
if count >= len(appsArr):
print('------------------------------------------------------------')
count = 0
# 自動檢測, 以應用名區分
def AutoCrawlUponApps():
# 設置計數器
count = 0
for appName in exampleAppName:
for marketName in marketsArr:
count = count + 1
DownloadTimes(marketName, appName)
if count >= len(marketsArr):
print('------------------------------------------------------------')
count = 0
# 更換方法名後Run
AutoCrawlUponApps()
Git下載
包括”百度”、”360”等18個Android手機、TV應用市場。
DTHunter
存在的問題
樂視、應用寶、91、Google Play皆顯示搜索失敗。
若有建議或意見,歡迎大家與我交流!