Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!

本次學習了手機抓包的相關知識,了解了Charles-mitmproxy-Appium的基本使用,通過對當當圖書評論的爬取,得以實踐。


/ 01 / Charles

Charles是一個APP抓包工具,與我之前最先使用的Filddler相似,可以得到手機App運行過程中發生的所有網絡請求和響應內容。


這里簡單說一下安裝。


電腦端下載安裝完Charles后,需要配置證書,最后開啟SSL監聽,這個具體大家自己自行百度。


手機端則是需要與電腦在同一網絡下,比如都連接家里的WIFI,然后在手機的WIFI高級選項里使用Charles代理,輸入電腦的IP地址,端口8888,最后為證書命名。


連好以后,手機打開當當App,到圖書「活著」的差評頁,不斷向下滑動差評頁面,便能在電腦上的Charles觀察到下面的信息。


Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖1

將電腦上的信息與手機上的信息匹配一下。


Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖2


這樣我們通過請求信息,就可以知道App評論的真正API接口了。


不過呢有的時候會碰見App接口帶有密匙的,我們不好確定出API接口,那么就輪到mitmproxy上場了。


Python騰訊大牛直播預約:

Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖3



/ 02 / mitmproxy


mitmproxy也是用來抓包的,是一個控制臺形式,我理解的就是沒有UI界面,在命令行上展示的(windows上不能用,我瞎理解的...)。


mitmproxy有兩個關聯組件,一個是mitmdump,是mitmproxy的命令行接口,可以對接Python腳本,用Python實現監聽后的處理,也就是用腳本處理信息。


另一個是mitmweb,為Web程序服務,本次不涉及。


mitmproxy的安裝同樣需要證書配置,電腦端配一個,手機端也要配一個。


這里有個坑,我的華為手機直接識別不了pem格式的文件,無法直接安裝,還得從SD卡那才能安裝,也就是有權限問題。


手機WIFI代理設置和Charles差不多,只是端口需要改變,這里是8080,。


然后命令行運行我都是在mitmdump.exe所在的文件夾開啟的,實在是不想去搞那些煩人的環境變量。


這里就直接講mitmdump的應用,畢竟windows用不了mitmproxy。


Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖4


通過手動下滑差評頁面,就能自動處理信息并存儲。


Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖5


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參數了。


Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖6


點擊藍色按鈕,手機便能自動啟動當當App啦!


接下來就是操作手機,然后點擊Appium的刷新鍵,獲取元素定位代碼,這里就完全用Appium上給的定位,懶得想,畢竟對手機網頁不是很懂...

{  左右滑動切換圖片  }

Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖7
Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖8
Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖9
Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖10


最后就是使用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(510)))


if __name__ == '__main__':
    main()


最后成功存儲數據。


Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖11



/ 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('生成詞云成功!')


最后生成差評詞云,來看看大家怎么吐槽的。


Python爬蟲實戰,selenium模塊,用Python實現手機抓包獲取當當圖書差評數據!的圖12


可以看出主要槽點就是「快遞物流」「書本質量」「客服服務」上 。

登錄后免費查看全文
立即登錄
App下載
技術鄰APP
工程師必備
  • 項目客服
  • 培訓客服
  • 平臺客服

TOP

14
6