文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。
作者: TED Crossin的編程教室
PS:如有需要Python學習資料的小伙伴可以加點擊下方鏈接自行獲取
http://note.youdao.com/noteshare?id=3054cce4add8a909e784ad934f956cef
知乎熱榜中的內容熱度值,是根據該條內容近24小時內的瀏覽量、互動量、專業加權、創作時間及在榜時間等維度,綜合計算得出的。知乎熱榜即根據內容熱度值制定的排行榜。
微博的熱度值是根據該篇微博被轉發、點贊數和微博發布時間等各項因素,來算出熱度基數,再與熱度權重相加,得出最終的熱度值。微博熱門即話題熱度排行榜。
今天我們要做的就是將相關排行榜中的話題內容爬取下來當作數據素材。換句話說,我們要把頁面上排好的信息,通過代碼讀取並保存起來。
1. 爬取網頁內容
Python 爬蟲通常采用 requests 庫來處理網絡請求。這里關於 requests 的方法和參數暫不展開。
知乎熱榜
微博熱門
這里有兩點要注意:
1、我們選用的網址鏈接在未登錄狀態下也可訪問,因此 requests 方法中的參數為空也不影響。但爬蟲時更多的情況是需要登陸狀態,因此也就要求通過設置不同參數來模擬登陸去進行相關操作。 2、通過 requests 模塊獲取的網頁內容,對應的是在網站上右鍵單擊,選擇“顯示網頁源代碼”后展現的頁面。它與我們實際看到的網頁內容或者 F12 進入開發者模式中看到的網頁 elements 是不同的。前者是網絡請求后返回結果,后者是瀏覽器對頁面渲染后結果。
2. 解析爬到的內容
第一步爬到的是整個頁面內容,接下來要在所有內容中去對目標定位,然后將其讀取並保存起來。
這里我采用的是 BeautifulSoup,因為學爬蟲最先接觸這個,用起來也蠻順手。通過 BeautifulSoup 提供的方法和參數,可以很便捷定位到目標。
在知乎熱榜的網頁源代碼中,拉到最下方可以看到如下:
在源代碼中網頁的 script 部分,有現成的整理好的熱榜數據。所以我們為了減少工作量,直接通過 BeautifulSoup 取出 script 中內容,再用正則表達式匹配熱榜數據列表處的內容。
1 import requests 2 import re 3 from bs4 import BeautifulSoup 4 5 headers={"User-Agent":"","Cookie":""} 6 zh_url = "https://www.zhihu.com/billboard" 7 zh_response = requests.get(zh_url,headers=headers) 8 9 webcontent = zh_response.text 10 soup = BeautifulSoup(webcontent,"html.parser") 11 script_text = soup.find("script",id="js-initialData").get_text() 12 rule = r'"hotList":(.*?),"guestFeeds"' 13 result = re.findall(rule,script_text) 14 15 temp = result[0].replace("false","False").replace("true","True") 16 hot_list = eval(temp) 17 print(hot_list)
這里我利用了 script 中熱榜數據的列表結構,在定位取出相關字符串后,先將 js 中的 true 和 false 轉化為 Python 中的 True 和 False,最后直接通過 eval() 來將字符串轉化為直接可用的數據列表。
運行代碼結果如圖:
至於對微博熱門的解析,就是中規中矩地利用 BeautifulSoup 來對網頁元素進行定位獲取:
1 import requests 2 from bs4 import BeautifulSoup 3 4 5 url = "https://s.weibo.com/top/summary" 6 headers={"User-Agent":"","Cookie":""} 7 wb_response = requests.get(url,headers=headers) 8 webcontent = wb_response.text 9 soup = BeautifulSoup(webcontent,"html.parser") 10 index_list = soup.find_all("td",class_="td-01") 11 title_list = soup.find_all("td",class_="td-02") 12 level_list = soup.find_all("td",class_="td-03") 13 14 topic_list = [] 15 for i in range(len(index_list)): 16 item_index = index_list[i].get_text(strip = True) 17 if item_index=="": 18 item_index = "0" 19 item_title = title_list[i].a.get_text(strip = True) 20 if title_list[i].span: 21 item_mark = title_list[i].span.get_text(strip = True) 22 else: 23 item_mark = "置頂" 24 item_level = level_list[i].get_text(strip = True) 25 topic_list.append({"index":item_index,"title":item_title,"mark":item_mark,"level":item_level,"link":f"https://s.weibo.com/weibo?q=%23{item_title}%23&Refer=top"}) 26 print(topic_list)
通過解析,將微博熱門數據逐條存入列表中:
后續對拿到的數據加以處理展示,即可得到很多有趣的應用或實現某些功能。例如集成諸多平台排行榜的 “今日熱榜”:
因為並未展開爬蟲細節,今天的總結也比較簡單:
1、首先在選取要爬的網址時要給自己降低難度,例如同樣是知乎熱榜,zhihu.com/hot 需要登陸,而 zhihu.com/billboard 無需登錄便可訪問 2、解析爬取到的內容時,要結合具體頁面內容選擇最便捷的方式。當需要批量爬取相似頁面時,也要盡量整理通用的解析策略。
完整代碼
weibo_top.py
1 import requests 2 from bs4 import BeautifulSoup 3 4 url = "https://s.weibo.com/top/summary" 5 headers = {"User-Agent": "", "Cookie": ""} 6 wb_response = requests.get(url, headers=headers) 7 webcontent = wb_response.text 8 soup = BeautifulSoup(webcontent, "html.parser") 9 index_list = soup.find_all("td", class_="td-01") 10 title_list = soup.find_all("td", class_="td-02") 11 level_list = soup.find_all("td", class_="td-03") 12 13 topic_list = [] 14 for i in range(len(index_list)): 15 item_index = index_list[i].get_text(strip=True) 16 if item_index == "": 17 item_index = "0" 18 item_title = title_list[i].a.get_text(strip=True) 19 if title_list[i].span: 20 item_mark = title_list[i].span.get_text(strip=True) 21 22 else: 23 item_mark = "置頂" 24 item_level = level_list[i].get_text(strip=True) 25 topic_list.append({"index": item_index, "title": item_title, "mark": item_mark, "level": item_level, 26 "link": f"https://s.weibo.com/weibo?q=%23{item_title}%23&Refer=top"}) 27 print(topic_list)
1 import requests 2 import re 3 from bs4 import BeautifulSoup 4 5 headers={"User-Agent":"","Cookie":""} 6 zh_url = "https://www.zhihu.com/billboard" 7 zh_response = requests.get(zh_url,headers=headers) 8 9 webcontent = zh_response.text 10 soup = BeautifulSoup(webcontent,"html.parser") 11 script_text = soup.find("script",id="js-initialData").get_text() 12 rule = r'"hotList":(.*?),"guestFeeds"' 13 result = re.findall(rule,script_text) 14 15 temp = result[0].replace("false","False").replace("true","True") 16 hot_list = eval(temp) 17 print(hot_list)