Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!
本次學習了手機抓包的相關知識,了解了Charles-mitmproxy-Appium的基本使用,通過對當當圖書評論的爬取,得以實踐。
/ 01 / Charles
Charles是一個APP抓包工具,與我之前最先使用的Filddler相似,可以得到手機App運行過程中發生的所有網絡請求和響應內容。
這里簡單說一下安裝。
電腦端下載安裝完Charles后,需要配置證書,最后開啟SSL監聽,這個具體大家自己自行百度。
手機端則是需要與電腦在同一網絡下,比如都連接家里的WIFI,然后在手機的WIFI高級選項里使用Charles代理,輸入電腦的IP地址,端口8888,最后為證書命名。
連好以后,手機打開當當App,到圖書「活著」的差評頁,不斷向下滑動差評頁面,便能在電腦上的Charles觀察到下面的信息。
將電腦上的信息與手機上的信息匹配一下。
這樣我們通過請求信息,就可以知道App評論的真正API接口了。
不過呢有的時候會碰見App接口帶有密匙的,我們不好確定出API接口,那么就輪到mitmproxy上場了。
Python騰訊大牛直播預約:

/ 02 / mitmproxy
mitmproxy也是用來抓包的,是一個控制臺形式,我理解的就是沒有UI界面,在命令行上展示的(windows上不能用,我瞎理解的...)。
mitmproxy有兩個關聯組件,一個是mitmdump,是mitmproxy的命令行接口,可以對接Python腳本,用Python實現監聽后的處理,也就是用腳本處理信息。
另一個是mitmweb,為Web程序服務,本次不涉及。
mitmproxy的安裝同樣需要證書配置,電腦端配一個,手機端也要配一個。
這里有個坑,我的華為手機直接識別不了pem格式的文件,無法直接安裝,還得從SD卡那才能安裝,也就是有權限問題。
手機WIFI代理設置和Charles差不多,只是端口需要改變,這里是8080,。
然后命令行運行我都是在mitmdump.exe所在的文件夾開啟的,實在是不想去搞那些煩人的環境變量。
這里就直接講mitmdump的應用,畢竟windows用不了mitmproxy。
通過手動下滑差評頁面,就能自動處理信息并存儲。
Python腳本如下,第一次深刻接觸腳本大佬,以前還只是聽說了游戲腳本而已。
import json
def response(flow):
url = 'product.mapi.dangdang.com'
page_size = 'page_size=15'
# 對url進行篩選,只選取評論的url
if url and page_size in flow.request.url:
text = flow.response.text
data = json.loads(text)
for item in data['review_list']:
# 獲取用戶昵稱
if len(item['cust_name']) > 0:
name = item['cust_name']
else:
name = '無名'
print(item['cust_name'])
# 獲取用戶評分
if len(item['score']) > 0:
score = str(item['score'])
else:
score = '0'
print(item['score'] + '\n')
# 獲取用戶評論
content = item['content'].replace(',', ',').replace('\n', '')
print(item['content'] + '\n')
# 獲取用戶評論時間
creation_date = item['creation_date']
print(item['creation_date'])
# 獲取有用數
if len(str(item['total_helpful_num'])) > 0 :
total_helpful_num = str(item['total_helpful_num'])
else:
total_helpful_num = '0'
print(item['total_helpful_num'])
# 獲取無用數
if len(str(item['total_useless_num'])) > 0 :
total_useless_num = str(item['total_useless_num'])
else:
total_useless_num = '0'
print(item['total_useless_num'])
# 獲取評論數
if len(str(item['total_reply_num'])) > 0 :
total_reply_num = str(item['total_reply_num'])
else:
total_reply_num = '0'
print(item['total_reply_num'])
print('\n')
# 將獲取信息寫入csv文件
with open('alive.csv', 'a+', encoding='utf-8-sig') as f:
f.write(name + ',' + score + ',' + content + ',' + creation_date + ',' + total_helpful_num + ',' + total_useless_num + ',' + total_reply_num + '\n')
那么我們現在已經實現了信息的獲取和存儲,是不是已經完成工作了呢?
并不是,我們還要實現自動化,上面可是手動下滑頁面啊!
感謝程序讓人解放雙手,實現自動化,佩服佩服。
/ 03 / Appium
Appium是移動端自動化測試工具,它可以模擬App內部的各種操作,本次用到就有「點擊」和「下滑」。
其實就跟selenium 一樣,只不過一個是電腦端自動化,一個是手機端自動化。
Appium安裝挺復雜的,而且新版本的命令還不一樣。
比如下滑,已經不能使用swip,而是使用TouchAction。
環境變量就是JDK,SDK等,坑太多,小伙伴慢慢體會...
都準備好了之后,將手機和電腦通過數據線連接,打開USB調試,允許訪問數據。
用adb命令獲取連接情況,及手機型號信息。
用SDK包下的aapt命令獲取APK的包名及入口名,這里不細說,有事找度娘。
這樣便能配置Appium參數了。
點擊藍色按鈕,手機便能自動啟動當當App啦!
接下來就是操作手機,然后點擊Appium的刷新鍵,獲取元素定位代碼,這里就完全用Appium上給的定位,懶得想,畢竟對手機網頁不是很懂...
{ 左右滑動切換圖片 }
最后就是使用Python代碼驅動App啦。
import time
import random
from appium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support import expected_conditions as EC
def main():
# 設置驅動配置
server = 'http://localhost:4723/wd/hub'
desired_caps = {
'platformName': 'Android',
'deviceName': 'STF_AL00',
'appPackage': 'com.dangdang.buy2',
'appActivity': 'com.dangdang.buy2.StartupActivity'
}
driver = webdriver.Remote(server, desired_caps)
# 這里獲取一下手機屏幕實際大小,可以為設置滑動參數做參考
size = driver.get_window_size()
print(size)
wait = WebDriverWait(driver, 60)
# 因為要叫我切換地區,選擇取消
button_1 = wait.until(EC.presence_of_element_located((By.ID, 'com.dangdang.buy2:id/left_bt')))
button_1.click()
# 點擊圖書榜按鈕
button_2 = wait.until(EC.presence_of_element_located((By.ID, 'com.dangdang.buy2:id/index_icon_iv0')))
button_2.click()
# 點擊圖書「活著」區域塊
button_3 = wait.until(EC.presence_of_element_located((By.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.support.v4.view.ViewPager/android.widget.RelativeLayout/android.widget.ListView/android.widget.LinearLayout[2]')))
button_3.click()
# 點擊評論區域塊
button_4 = wait.until(EC.presence_of_element_located((By.ID, 'com.dangdang.buy2:id/product_component_book_score_ll')))
button_4.click()
time.sleep(5)
# 點擊差評按鈕
button_5 = wait.until(EC.presence_of_element_located((By.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.support.v4.view.ViewPager/android.widget.LinearLayout/android.support.v4.view.ViewPager/android.widget.RelativeLayout/android.widget.LinearLayout/android.view.ViewGroup/android.widget.RelativeLayout[6]/android.widget.TextView')))
button_5.click()
# 向下滑動,y軸參數我隨便選的,向上滑就對了
while True:
TouchAction(driver).press(x=515, y=1247).move_to(x=515, y=1026).release().perform()
time.sleep(float(random.randint(5, 10)))
if __name__ == '__main__':
main()
最后成功存儲數據。
/ 04 / 數據可視化
詞云代碼如下。
from wordcloud import WordCloud, ImageColorGenerator
import matplotlib.pyplot as plt
import pandas as pd
import jieba
df = pd.read_excel('alive.xlsx', header=None, names=["name", "score", "comment", "date", "up_number", "down_number", "reply_number"])
text = ''
for line in df['comment']:
text += ' '.join(jieba.cut(line, cut_all=False))
backgroud_Image = plt.imread('book.jpg')
stopwords = set('')
stopwords.update(['沒有', '什么', '不是', '知道', '怎么', '就是', '本書', '當當', '這個 商品', '一個', '自己', '真的', '商品 不太好', '一本', '這樣', '但是', '現在', '你們', '一直', '以后', '這個', '商品'])
wc = WordCloud(
background_color='white',
mask=backgroud_Image,
font_path='C:\Windows\Fonts\STZHONGS.TTF',
max_words=2000,
max_font_size=150,
random_state=30,
stopwords=stopwords
)
wc.generate_from_text(text)
# 看看詞頻高的有哪些,把無用信息去除
process_word = WordCloud.process_text(wc, text)
sort = sorted(process_word.items(), key=lambda e:e[1], reverse=True)
print(sort[:50])
img_colors = ImageColorGenerator(backgroud_Image)
wc.recolor(color_func=img_colors)
plt.imshow(wc)
plt.axis('off')
wc.to_file("活著.jpg")
print('生成詞云成功!')
最后生成差評詞云,來看看大家怎么吐槽的。
可以看出主要槽點就是「快遞物流」「書本質量」「客服服務」上 。
工程師必備
- 項目客服
- 培訓客服
- 平臺客服
TOP




















