本文詳細介紹了如何利用python實現微博評論的爬取,可以爬取指定微博下的評論。基於的策略是找到微博評論接口,先登錄微博,獲取cookies,使用requests庫發送請求,並且將數據存儲到.csv文件中。用到的庫request,
首先微博的站點有四個,pc 端weibo.com、weibo.cn以及移動端m.weibo.com(無法在電腦上瀏覽)、https://m.weibo.cn。在網上大致瀏覽了一下,普遍都認為移動端爬取比較容易,故選擇移動端https://m.weibo.cn進行爬取。
登陸m.weibo.cn之后,找到指定微博,例如如下微博https://m.weibo.cn/detail/4493649780161355:
F12打開開發者模式,點擊如下圖選項,找到評論所在接口
找到接口以及文本內容之后,就是分析請求的url構造規律,找到第一個被請求數據的第一個url:
https://m.weibo.cn/comments/hotflow?id=4493649780161355&mid=4493649780161355&max_id_type=0
下拉頁面,找到第存在目標數據的二個類似的url:
https://m.weibo.cn/comments/hotflow?id=4493649780161355&mid=4493649780161355&max_id=13883565036443296&max_id_type=0
第三個url:
https://m.weibo.cn/comments/hotflow?id=4493649780161355&mid=4493649780161355&max_id=139259509575025&max_id_type=0
...
比較之后我們發現url 的構造字段為https://m.weibo.cn/comments/hotflow? 后面跟上 id=value & mid=vlaue & max_id=value,其中id和mid的值經分析是不會改變的,第一條url中無max_id,往后max_id的值都會發生改變。接着我們在瀏覽器開發者模式中查看請求返回的數據,例如第一個url請求返回的數據其中就包含max_id 的值且等於第二個url中max_id 的值
因此我們可以使用一個遞歸函數,將回去的max_id的值返回,用於構造下一次請求的url, 代碼如下:
1 import requests 2 import random 3 import time 4 import re 5 import json 6 import csv 7 8 start_url = 'https://m.weibo.cn/comments/hotflow?id=4493649780161355&mid=4493649780161355&max_id_type=0' # 首個url 9 next_url = '"https://m.weibo.cn/comments/hotflow?id=4493649780161355&mid=4493649780161355&max_id={}&max_id_type=0"' # 用於構造后面的url的模板 10 11 continue_url = start_url 12 13 headers = { 14 'cookie': '', # 傳入你自己的cookie 15 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36', 16 } 17 count = 0 18 19 fileHeader = ["id","評論時間","用戶ID","昵稱","評論樓層","評論內容"] 20 21 22 23 def get_data(url): 24 for trytime in range(3): # 允許超時次數為3次 25 try: 26 response = requests.get(url=url, headers=headers, timeout=5) 27 data = json.loads(response.text) 28 if response.status_code == 200: 29 break 30 except: 31 print('超時') 32 33 if trytime == 2: # 連續3次超時就退出遞歸 34 print('連續3次超時') 35 return 36 37 if data['ok'] == 0: # 若沒有獲取到數據也進行退出 38 print("獲取到的數據data['ok']=", 0) 39 return 40 41 elif data['ok'] == 1: # 判斷若能夠獲取到數據 則進行所需數據提取,並且構造下次請求的url,調用函數 42 max_id = data.get("data").get("max_id") 43 comments = data.get('data').get('data') 44 for item in comments: 45 ''' 獲取內容creattime;floor——number;text;userid;screen——name;''' 46 global count 47 count += 1 48 create_time = item['created_at'] 49 floor_number = item['floor_number'] 50 text = ''.join(re.findall('[\u4e00-\u9fa5]', item['text'])) # 匹配文本內容 51 userid = item.get('user')['id'] 52 screen_name = item.get('user')['screen_name'] 53 54 # 將內容寫入csv文件中 55 csv_opreator([count,create_time,userid,screen_name,floor_number,text]) 56 57 print([count, create_time, userid, screen_name, floor_number, text]) 58 print("第{}條數據獲取成功".format(count)) 59 60 global next_url 61 continue_url = next_url.format(str(max_id)) 62 print(continue_url) 63 time.sleep(random.random()*5) 64 get_data(continue_url) # 調用函數本身 65 return 66 67 def csv_opreator(a): 68 69 with open("weibocoments.csv", "a") as f: 70 writer = csv.writer(f) 71 writer.writerow(a) 72 73 74 75 if __name__ == "__main__": 76 csv_opreator(fileHeader) 77 get_data(continue_url)
后台輸出如下:
csv文件結果如下:
可能遇到的問題,由於微博反爬,可先選擇更換ip,或者重新登陸,將新的cookies復制進代碼。