這幾天琢磨怎么從手機app爬取帖子數(shù)據(jù)。因為網(wǎng)上的很多教程年久失效了,所以自己花了好些功夫才弄明白百度貼吧的請求機制。
太長不看版
百度貼吧有三種訪問方式:
- PC網(wǎng)頁端。在電腦端chrome瀏覽器輸入url訪問貼吧。
- 手機網(wǎng)頁端。在手機端瀏覽器輸入url訪問貼吧。
- 手機app端。在百度貼吧app內訪問貼吧。
三種訪問方式的頁面風格不同,訪問時使用的域名、請求內容也不盡相同:
- PC網(wǎng)頁端:
- 訪問貼吧時,用GET請求
https://tieba.baidu.com/f?kw={貼吧名}
。 - 訪問帖子時,用GET請求
https://tieba.baidu.com/p/{帖子id}
- 訪問貼吧時,用GET請求
- 手機網(wǎng)頁端:
- 在訪問貼吧時,請求域名同上,但要在header的user-agent屬性中要填寫手機端屬性,在響應中并不包含帖子列表。實際上,帖子列表信息是通過另外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
得到的,響應格式為json。 - 訪問帖子時,請求域名同上,但帖子的內容是通過另外GET請求
https://tieba.baidu.com/mg/p/getPbData?kz={帖子id}&obj_param2=chrome&format=json&eqid=&refer=&pn=1&rn=5
得到的,其中pn為頁號 - 總結而言,雖然主功能的域名與PC端一致,但數(shù)據(jù)是通過另外的請求得到的。
- 在訪問貼吧時,請求域名同上,但要在header的user-agent屬性中要填寫手機端屬性,在響應中并不包含帖子列表。實際上,帖子列表信息是通過另外GET請求
- 手機app端:
- 在訪問貼吧時的請求與響應格式未知。
- 用POST請求
http://tiebac.baidu.com/c/f/pb/page?cmd=302001&format=protobuf
,在body會填寫包含帖子id的信息,但格式未知。響應是protobuf形式,用protoc.exe --decode_raw < req
可以解析數(shù)據(jù)值,但各個變量名未知。
三種訪問方式的功能各不相同:
- PC網(wǎng)頁端訪問貼吧時,只顯示帖子的回復數(shù),不顯示點贊數(shù)。訪問帖子時,能使用“只看樓主”功能
- 手機網(wǎng)頁端訪問貼吧時,能顯示點贊數(shù)。訪問帖子時,無法使用“只看樓主”功能。
- 手機app端訪問貼吧時,能顯示點贊數(shù)。訪問帖子時,能使用“只看樓主”功能。但筆者無法解析器請求和響應格式。
PC端的爬取方法
在闡述手機版貼吧的爬取方法前,首先闡述下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)
得到以下響應,可以看到,響應有完整的html格式,還有"回復"一欄:
之后用bs4解析html元素即可獲取想要的信息。但本文希望爬取帖子的點贊數(shù),而這個信息只存在于手機端bd的響應中。
手機網(wǎng)頁版的爬取方法
參考爬蟲(六)爬取任意,獲取標題、詳情頁地址及圖片(手機版)
如何在chrome訪問網(wǎng)頁的手機版本
按F12,點擊圖中箭頭所示標記,然后F5刷新網(wǎng)頁,即可訪問手機版本。
找到的帖子信息
在F12->網(wǎng)絡下可以找到該標簽頁發(fā)出的所有網(wǎng)絡請求,其中界面的URLhttps://tieba.baidu.com/f?kw=%E5%AD%99%E7%AC%91%E5%B7%9D
給出的響應中,只看到了加載script的字樣,并沒有包含主題帖子的各種信息,比如標題、作者、點贊數(shù)等等。有理由推測,PC端和手機端bd加載帖子內容的加載機制并不同,手機端并不會在第一次請求中返回內容,而是在后續(xù)的請求中再獲取。
下圖是一個帖子的內容,并沒在第一次請求中返回。
我們清楚,F(xiàn)12的"網(wǎng)絡"頁包含了標簽頁的所有網(wǎng)絡請求,所以既然要加載帖子內容,它必定是在某次網(wǎng)絡請求中獲取的。所以順著看到了下圖箭頭所指的請求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
這個請求中。
深入到帖子內部,查看"網(wǎng)絡"可知,訪問帖子域名為https://tieba.baidu.com/p/8234233310#/
,拉取內容的域名為https://tieba.baidu.com/mg/p/getPbData?kz=8234233310&obj_param2=chrome&format=json&eqid=&refer=&pn=1&rn=5
,其中pn
代表回帖頁數(shù)。
手機端app的爬取方法
訪問貼吧的請求域名難易確定,請求機制難易理解。
訪問帖子時的請求響應格式難易理解: