這幾天琢磨怎么從手機(jī)app爬取帖子數(shù)據(jù)。因為網(wǎng)上的很多教程年久失效了,所以自己花了好些功夫才弄明白百度貼吧的請求機(jī)制。
太長不看版
百度貼吧有三種訪問方式:
- PC網(wǎng)頁端。在電腦端chrome瀏覽器輸入url訪問貼吧。
- 手機(jī)網(wǎng)頁端。在手機(jī)端瀏覽器輸入url訪問貼吧。
- 手機(jī)app端。在百度貼吧app內(nèi)訪問貼吧。
三種訪問方式的頁面風(fēng)格不同,訪問時使用的域名、請求內(nèi)容也不盡相同:
- PC網(wǎng)頁端:
- 訪問貼吧時,用GET請求
https://tieba.baidu.com/f?kw={貼吧名}。 - 訪問帖子時,用GET請求
https://tieba.baidu.com/p/{帖子id}
- 訪問貼吧時,用GET請求
- 手機(jī)網(wǎng)頁端:
- 在訪問貼吧時,請求域名同上,但要在header的user-agent屬性中要填寫手機(jī)端屬性,在響應(yīng)中并不包含帖子列表。實(shí)際上,帖子列表信息是通過另外GET請求
https://tieba.baidu.com/mg/f/getFrsData?kw={貼吧名}&rn=10&pn={頁號}&is_good=0&cid=0&sort_type=0&fr=&default_pro=1&only_thread_list=0&eqid=&refer=wappass.baidu.com得到的,響應(yīng)格式為json。 - 訪問帖子時,請求域名同上,但帖子的內(nèi)容是通過另外GET請求
https://tieba.baidu.com/mg/p/getPbData?kz={帖子id}&obj_param2=chrome&format=json&eqid=&refer=&pn=1&rn=5得到的,其中pn為頁號 - 總結(jié)而言,雖然主功能的域名與PC端一致,但數(shù)據(jù)是通過另外的請求得到的。
- 在訪問貼吧時,請求域名同上,但要在header的user-agent屬性中要填寫手機(jī)端屬性,在響應(yīng)中并不包含帖子列表。實(shí)際上,帖子列表信息是通過另外GET請求
- 手機(jī)app端:
- 在訪問貼吧時的請求與響應(yīng)格式未知。
- 用POST請求
http://tiebac.baidu.com/c/f/pb/page?cmd=302001&format=protobuf,在body會填寫包含帖子id的信息,但格式未知。響應(yīng)是protobuf形式,用protoc.exe --decode_raw < req可以解析數(shù)據(jù)值,但各個變量名未知。
三種訪問方式的功能各不相同:
- PC網(wǎng)頁端訪問貼吧時,只顯示帖子的回復(fù)數(shù),不顯示點(diǎn)贊數(shù)。訪問帖子時,能使用“只看樓主”功能
- 手機(jī)網(wǎng)頁端訪問貼吧時,能顯示點(diǎn)贊數(shù)。訪問帖子時,無法使用“只看樓主”功能。
- 手機(jī)app端訪問貼吧時,能顯示點(diǎn)贊數(shù)。訪問帖子時,能使用“只看樓主”功能。但筆者無法解析器請求和響應(yīng)格式。
PC端的爬取方法
在闡述手機(jī)版貼吧的爬取方法前,首先闡述下PC端的做法。訪問孫笑川吧的urlhttps://tieba.baidu.com/f?kw=%E5%AD%99%E7%AC%91%E5%B7%9D,得到如下頁面,

在python程序中使用requests+bs4訪問該網(wǎng)頁,
# 使用requests
import requests
from bs4 import BeautifulSoup
import os
html_doc = requests.get("https://tieba.baidu.com/f?kw=%E5%AD%99%E7%AC%91%E5%B7%9D", verify=False)
soup = BeautifulSoup(html_doc.content, 'lxml')
print(soup)
得到以下響應(yīng),可以看到,響應(yīng)有完整的html格式,還有"回復(fù)"一欄:

之后用bs4解析html元素即可獲取想要的信息。但本文希望爬取帖子的點(diǎn)贊數(shù),而這個信息只存在于手機(jī)端bd的響應(yīng)中。
手機(jī)網(wǎng)頁版的爬取方法
參考爬蟲(六)爬取任意,獲取標(biāo)題、詳情頁地址及圖片(手機(jī)版)
如何在chrome訪問網(wǎng)頁的手機(jī)版本
按F12,點(diǎn)擊圖中箭頭所示標(biāo)記,然后F5刷新網(wǎng)頁,即可訪問手機(jī)版本。

找到的帖子信息
在F12->網(wǎng)絡(luò)下可以找到該標(biāo)簽頁發(fā)出的所有網(wǎng)絡(luò)請求,其中界面的URLhttps://tieba.baidu.com/f?kw=%E5%AD%99%E7%AC%91%E5%B7%9D給出的響應(yīng)中,只看到了加載script的字樣,并沒有包含主題帖子的各種信息,比如標(biāo)題、作者、點(diǎn)贊數(shù)等等。有理由推測,PC端和手機(jī)端bd加載帖子內(nèi)容的加載機(jī)制并不同,手機(jī)端并不會在第一次請求中返回內(nèi)容,而是在后續(xù)的請求中再獲取。

下圖是一個帖子的內(nèi)容,并沒在第一次請求中返回。

我們清楚,F(xiàn)12的"網(wǎng)絡(luò)"頁包含了標(biāo)簽頁的所有網(wǎng)絡(luò)請求,所以既然要加載帖子內(nèi)容,它必定是在某次網(wǎng)絡(luò)請求中獲取的。所以順著看到了下圖箭頭所指的請求https://tieba.baidu.com/mg/f/getFrsData?kw=%E5%AD%99%E7%AC%91%E5%B7%9D&rn=10&pn=1&is_good=0&cid=0&sort_type=0&fr=&default_pro=1&only_thread_list=0&eqid=&refer=tieba.baidu.com,

所以,拉取帖子數(shù)據(jù)的動作就在/f/getFrsData?kw=%E5%AD%99%E7%AC%91%E5%B7%9D這個請求中。
深入到帖子內(nèi)部,查看"網(wǎng)絡(luò)"可知,訪問帖子域名為https://tieba.baidu.com/p/8234233310#/,拉取內(nèi)容的域名為https://tieba.baidu.com/mg/p/getPbData?kz=8234233310&obj_param2=chrome&format=json&eqid=&refer=&pn=1&rn=5,其中pn代表回帖頁數(shù)。
手機(jī)端app的爬取方法
訪問貼吧的請求域名難易確定,請求機(jī)制難易理解。
訪問帖子時的請求響應(yīng)格式難易理解:
