Python實現(xiàn)爬取馬云的微博功能示例
本文實例講述了Python實現(xiàn)爬取馬云的微博功能。分享給大家供大家參考,具體如下:
分析請求
我們打開 Ajax 的 XHR 過濾器,然后一直滑動頁面加載新的微博內(nèi)容,可以看到會不斷有Ajax請求發(fā)出。
我們選定其中一個請求來分析一下它的參數(shù)信息,點擊該請求進入詳情頁面,如圖所示:
可以發(fā)現(xiàn)這是一個 GET 請求,請求的參數(shù)有 6 個:display、retcode、type、value、containerid 和 page,觀察這些請求可以發(fā)現(xiàn)只有 page 在變化,很明顯 page 是用來控制分頁的。
分析響應
如圖所示:
它是一個 Json 格式,瀏覽器開發(fā)者工具自動為做了解析方便我們查看,可以看到最關(guān)鍵的兩部分信息就是 cardlistInfo 和 cards,將二者展開,cardlistInfo 里面包含了一個比較重要的信息就是 total,經(jīng)過觀察后發(fā)現(xiàn)其實它是微博的總數(shù)量,我們可以根據(jù)這個數(shù)字來估算出分頁的數(shù)目。
發(fā)現(xiàn)它又有一個比較重要的字段,叫做 mblog,繼續(xù)把它展開,發(fā)現(xiàn)它包含的正是微博的一些信息。比如 attitudes_count 贊數(shù)目、comments_count 評論數(shù)目、reposts_count 轉(zhuǎn)發(fā)數(shù)目、created_at 發(fā)布時間、text 微博正文等等,得來全不費功夫,而且都是一些格式化的內(nèi)容,所以我們提取信息也更加方便了。
這樣我們可以請求一個接口就得到 10 條微博,而且請求的時候只需要改變 page 參數(shù)即可。這樣我們只需要簡單做一個循環(huán)就可以獲取到所有的微博了。
實戰(zhàn)演練
在這里我們就開始用程序來模擬這些 Ajax 請求,將馬云的所有微博全部爬取下來。
首先我們定義一個方法,來獲取每次請求的結(jié)果,在請求時page 是一個可變參數(shù),所以我們將它作為方法的參數(shù)傳遞進來,代碼如下:
from urllib.parse import urlencode import requests base_url = 'https://m.weibo.cn/api/container/getIndex?' headers = { 'Host': 'm.weibo.cn', 'Referer': 'https://m.weibo.cn/u/2145291155', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest', } def get_page(page): params = { 'display': '0', 'retcode': '6102', 'type': 'uid', 'value': '2145291155', 'containerid': '1076032145291155', 'page': page } url = base_url + urlencode(params) try: response = requests.get(url, headers=headers) if response.status_code == 200: return response.json() except requests.ConnectionError as e: print('Error', e.args)
首先在這里我們定義了一個 base_url 來表示請求的 URL 的前半部分,接下來構(gòu)造了一個參數(shù)字典,其中 display、retcode、 type、value、containerid 是固定的參數(shù),只有 page 是可變參數(shù),接下來我們調(diào)用了 urlencode() 方法將參數(shù)轉(zhuǎn)化為 URL 的 GET請求參數(shù),即類似于display=0&retcode=6102&type=uid&value=2145291155&containerid=1076032145291155&page=2 這樣的形式,隨后 base_url 與參數(shù)拼合形成一個新的 URL,然后我們用 Requests 請求這個鏈接,加入 headers 參數(shù),然后判斷響應的狀態(tài)碼,如果是200,則直接調(diào)用 json() 方法將內(nèi)容解析為 Json 返回,否則不返回任何信息,如果出現(xiàn)異常則捕獲并輸出其異常信息。
隨后我們需要定義一個解析方法,用來從結(jié)果中提取我們想要的信息,比如我們這次想保存微博的 正文、贊數(shù)、評論數(shù)、轉(zhuǎn)發(fā)數(shù)這幾個內(nèi)容,那可以先將 cards 遍歷,然后獲取 mblog 中的各個信息,賦值為一個新的字典返回即可。
from pyquery import PyQuery as pq def parse_page(json): if json: items = json.get('cards') for item in items: item = item.get('mblog') weibo = {} weibo['微博內(nèi)容:'] = pq(item.get('text')).text() weibo['轉(zhuǎn)發(fā)數(shù)'] = item.get('attitudes_count') weibo['評論數(shù)'] = item.get('comments_count') weibo['點贊數(shù)'] = item.get('reposts_count') yield weibo
在這里我們借助于 PyQuery 將正文中的 HTML 標簽去除掉。
最后我們遍歷一下 page,將提取到的結(jié)果打印輸出即可。
if __name__ == '__main__': for page in range(1, 50): json = get_page(page) results = parse_page(json) for result in results: print(result)
另外我們還可以加一個方法將結(jié)果保存到 本地 TXT 文件中。
def save_to_txt(result): with open('馬云的微博.txt', 'a', encoding='utf-8') as file: file.write(str(result) + '\n')
代碼整理
import requests from urllib.parse import urlencode from pyquery import PyQuery as pq base_url = 'https://m.weibo.cn/api/container/getIndex?' headers = { 'Host': 'm.weibo.cn', 'Referer': 'https://m.weibo.cn/u/2145291155', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest', } max_page = 50 def get_page(page): params = { 'display': '0', 'retcode': '6102', 'type': 'uid', 'value': '2145291155', 'containerid': '1076032145291155', 'page': page } url = base_url + urlencode(params) try: response = requests.get(url, headers=headers) if response.status_code == 200: return response.json(), page except requests.ConnectionError as e: print('Error', e.args) def parse_page(json, page: int): if json: items = json.get('data').get('cards') for index, item in enumerate(items): if page == 1 and index == 1: continue else: item = item.get('mblog') weibo = {} weibo['微博內(nèi)容:'] = pq(item.get('text')).text() weibo['轉(zhuǎn)發(fā)數(shù):'] = item.get('attitudes_count') weibo['評論數(shù):'] = item.get('comments_count') weibo['點贊數(shù):'] = item.get('reposts_count') yield weibo def save_to_txt(result): with open('馬云的微博.txt', 'a', encoding='utf-8') as file: file.write(str(result) + '\n') if __name__ == '__main__': for page in range(1, max_page + 1): json = get_page(page) results = parse_page(*json) for result in results: print(result) save_to_txt(result)
本文參考崔慶才的《python3 網(wǎng)絡(luò)爬蟲開發(fā)實戰(zhàn)》。
希望本文所述對大家Python程序設(shè)計有所幫助。
相關(guān)文章
python3的一個天坑問題及解決方法:報錯UnicodeDecodeError: ‘utf-8‘
在調(diào)試程序發(fā)現(xiàn)python3的一個天坑問題:報錯UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xa3 in position 59: invalid,特此曝光,為眾位開發(fā)朋友提個醒2023-09-09基于python的Tkinter實現(xiàn)一個簡易計算器
這篇文章主要介紹了基于python的Tkinter實現(xiàn)一個簡易計算器的相關(guān)資料,還為大家分享了僅用用50行Python代碼實現(xiàn)的簡易計算器,感興趣的小伙伴們可以參考一下2015-12-12Python遠程開發(fā)環(huán)境部署與調(diào)試過程圖解
這篇文章主要介紹了Python遠程開發(fā)環(huán)境部署與調(diào)試過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-12-12Python字典查找數(shù)據(jù)的5個基礎(chǔ)操作方法
Python字典是另一種可變?nèi)萜髂P?且可存儲任意類型對象,如字符串、數(shù)字、元組等其他容器模型,下面這篇文章主要給大家介紹了關(guān)于Python字典查找數(shù)據(jù)的5個基礎(chǔ)操作方法,需要的朋友可以參考下2022-06-06