在這個萬物互聯的時代,手機端(App)、電腦端(Web),連接配接着你我他。
本次學習了手機抓包的相關知識,了解了Charles-mitmproxy-Appium的基本使用,通過對當當圖書評論的爬取,得以實踐。
那麼就讓我們來看看當當圖書「活着」的差評吧!
/ 01 / Charles
Charles是一個APP抓包工具,與我之前最先使用的Filddler相似,可以得到手機App運作過程中發生的所有網絡請求和響應内容。
這裡簡單說一下安裝。
電腦端下載下傳安裝完Charles後,需要配置證書,最後開啟SSL監聽,這個具體大家自己自行百度。
手機端則是需要與電腦在同一網絡下,比如都連接配接家裡的WIFI,然後在手機的WIFI進階選項裡使用Charles代理,輸入電腦的IP位址,端口8888,最後為證書命名。
連好以後,手機打開當當App,到圖書「活着」的差評頁,不斷向下滑動差評頁面,便能在電腦上的Charles觀察到下面的資訊。

這樣我們通過請求資訊,就可以知道App評論的真正API接口了。
不過呢有的時候會碰見App接口帶有密匙的,我們不好确定出API接口,那麼就輪到mitmproxy上場了。
/ 02 / mitmproxy
mitmproxy也是用來抓包的,是一個控制台形式,我了解的就是沒有UI界面,在指令行上展示的(windows上不能用,我瞎了解的...)。
mitmproxy有兩個關聯元件,一個是mitmdump,是mitmproxy的指令行接口,可以對接Python腳本,用Python實作監聽後的處理,也就是用腳本處理資訊。
另一個是mitmweb,為Web程式服務,本次不涉及。
mitmproxy的安裝同樣需要證書配置,電腦端配一個,手機端也要配一個。
這裡有個坑,我的華為手機直接識别不了pem格式的檔案,無法直接安裝,還得從SD卡那才能安裝,也就是有權限問題。
手機WIFI代理設定和Charles差不多,隻是端口需要改變,這裡是8080,。
然後指令行運作我都是在mitmdump.exe所在的檔案夾開啟的,實在是不想去搞那些煩人的環境變量。
這裡就直接講mitmdump的應用,畢竟windows用不了mitmproxy。
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'])
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'])
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'])
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'])
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('生成詞雲成功!')
最後生成差評詞雲,來看看大家怎麼吐槽的。
可以看出主要槽點就是「快遞物流」「書本品質」「客服服務」上 。
畢竟「活着」這本書,内容還是不錯的,從中深深的體會到生活的不易~
文末點個贊,比心!!!
原文釋出時間為: 2018-11-27
本文作者:法納斯特
本文來自雲栖社群合作夥伴“
Python資料之道”,了解相關資訊可以關注“
”。