【Python3爬蟲】微博用戶爬蟲

這次爬蟲要實現的是爬取某個微博用戶的關注和粉絲的用戶公開基本信息,包括用戶暱稱、id、性別、所在地和其粉絲數量,而後將爬取下來的數據保存在MongoDB數據庫中,最後再生成幾個圖表來簡單分析一下咱們獲得的數據。git

 

1、具體步驟:

這裏咱們選取的爬取站點是https://m.weibo.cn,此站點是微博移動端的站點,咱們能夠直接查看某個用戶的微博,好比https://m.weibo.cn/profile/5720474518
github

而後查看其關注的用戶,打開開發者工具,切換到XHR過濾器,一直下拉列表,就會看到有不少的Ajax請求。這些請求的類型是Get類型,返回結果是Json格式,展開以後就能看到有不少用戶的信息。
數據庫

這些請求有兩個參數,containerid和page,經過改變page的數值,咱們就能獲得更多的請求了。獲取其粉絲的用戶信息的步驟是同樣的,除了請求的連接不一樣以外,參數也不一樣,修改一下就能夠了。json

因爲這些請求返回的結果裏只有用戶的名稱和id等信息,並無包含用戶的性別等基本資料,因此咱們點進某我的的微博,而後查看其基本資料,好比這個,打開開發者工具,能夠找到下面這個請求:api

因爲這我的的id是6857214856,所以咱們能夠發現當咱們獲得一我的的id的時候,就能夠構造獲取基本資料的連接和參數了,相關代碼以下(uid就是用戶的id):app

 1 uid_str = "230283" + str(uid)  2 url = "https://m.weibo.cn/api/container/getIndex?containerid={}_-_INFO&title=%E5%9F%BA%E6%9C%AC%E8%B5%84%E6%96%99&luicode=10000011&lfid={}&featurecode=10000326".format(uid_str, uid_str)  3 data = {  4     "containerid": "{}_-_INFO".format(uid_str),  5     "title": "基本資料",  6     "luicode": 10000011,  7     "lfid": int(uid_str),  8     "featurecode": 10000326
 9 }

而後這個返回的結果也是Json格式,提取起來就很方便,由於不少人的基本資料都不怎麼全,因此我提取了用戶暱稱、性別、所在地和其粉絲數量。並且由於一些帳號並不是我的帳號,就沒有性別信息,對於這些帳號,我選擇將其性別設置爲男性。不過在爬取的時候,我發現一個問題,就是當頁數超過250的時候,返回的結果就已經沒有內容了,也就是說這個方法最多隻能爬250頁。對於爬取下來的用戶信息,全都保存在MongoDB數據庫中,而後在爬取結束以後,讀取這些信息並繪製了幾個圖表,分別繪製了男女比例扇形圖、用戶所在地分佈圖和用戶的粉絲數量柱狀圖。dom

 

2、主要代碼:

因爲第一頁返回的結果和其餘頁返回的結果格式是不一樣的,因此要分別進行解析,並且由於部分結果的json格式不一樣,因此可能報錯,所以採用了try...except...把出錯緣由打印出來。ide

爬取第一頁並解析的代碼以下:工具

 1 def get_and_parse1(url):  2     res = requests.get(url)  3     cards = res.json()['data']['cards']  4     info_list = []  5     try:  6         for i in cards:  7             if "title" not in i:  8                 for j in i['card_group'][1]['users']:  9                     user_name = j['screen_name']  # 用戶名
10                     user_id = j['id']  # 用戶id
11                     fans_count = j['followers_count']  # 粉絲數量
12                     sex, add = get_user_info(user_id) 13                     info = { 14                         "用戶名": user_name, 15                         "性別": sex, 16                         "所在地": add, 17                         "粉絲數": fans_count, 18  } 19  info_list.append(info) 20             else: 21                 for j in i['card_group']: 22                     user_name = j['user']['screen_name']  # 用戶名
23                     user_id = j['user']['id']  # 用戶id
24                     fans_count = j['user']['followers_count']  # 粉絲數量
25                     sex, add = get_user_info(user_id) 26                     info = { 27                         "用戶名": user_name, 28                         "性別": sex, 29                         "所在地": add, 30                         "粉絲數": fans_count, 31  } 32  info_list.append(info) 33         if "followers" in url: 34             print("第1頁關注信息爬取完畢...") 35         else: 36             print("第1頁粉絲信息爬取完畢...") 37  save_info(info_list) 38     except Exception as e: 39         print(e)

爬取其餘頁並解析的代碼以下:ui

 1 def get_and_parse2(url, data):  2     res = requests.get(url, headers=get_random_ua(), data=data)  3     sleep(3)  4     info_list = []  5     try:  6         if 'cards' in res.json()['data']:  7             card_group = res.json()['data']['cards'][0]['card_group']  8         else:  9             card_group = res.json()['data']['cardlistInfo']['cards'][0]['card_group'] 10         for card in card_group: 11             user_name = card['user']['screen_name']  # 用戶名
12             user_id = card['user']['id']  # 用戶id
13             fans_count = card['user']['followers_count']  # 粉絲數量
14             sex, add = get_user_info(user_id) 15             info = { 16                 "用戶名": user_name, 17                 "性別": sex, 18                 "所在地": add, 19                 "粉絲數": fans_count, 20  } 21  info_list.append(info) 22         if "page" in data: 23             print("第{}頁關注信息爬取完畢...".format(data['page'])) 24         else: 25             print("第{}頁粉絲信息爬取完畢...".format(data['since_id'])) 26  save_info(info_list) 27     except Exception as e: 28         print(e)

 

3、運行結果:

在運行的時候可能會出現各類各樣的錯誤,有的時候返回結果爲空,有的時候解析出錯,不過仍是能成功爬取大部分數據的,這裏就放一下最後生成的三張圖片吧。

 

 

完整代碼已上傳到GitHub

相關文章
相關標籤/搜索