一直也沒寫過爬蟲的代碼,一來是接觸練習的少,二來也對爬蟲心存偏見:老有種做賊偷數據的感覺。
最近在體驗過爬蟲的高效便捷后,覺得確實有必要多實踐一下。其實我本身學爬蟲沒多久,遠沒到分享爬蟲技術的水平。但公眾號平臺嘛,又不是課堂,分享點實戰經驗和思路,相互交流下心得,也是挺不錯的。
私信小編01 領取完整代碼!
今天來分享下這兩天寫的入門級的爬取知乎熱榜和微博熱門數據的代碼和思路。首先明確下爬蟲、知乎熱榜和微博熱門這些概念。
網絡爬蟲(又稱為網頁蜘蛛,網絡機器人,在FOAF社區中間,更經常的稱為網頁追逐者),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。
——百度百科,“網絡爬蟲”
知乎熱榜中的內容熱度值,是根據該條內容近24小時內的瀏覽量、互動量、專業加權、創作時間及在榜時間等維度,綜合計算得出的。知乎熱榜即根據內容熱度值制定的排行榜。
???????知乎熱榜鏈接:https://www.zhihu.com/billboardhttps://www.zhihu.com/hot
微博的熱度值是根據該篇微博被轉發、點贊數和微博發布時間等各項因素,來算出熱度基數,再與熱度權重相加,得出最終的熱度值。微博熱門即話題熱度排行榜。
??????微博熱門鏈接:https://s.weibo.com/top/summary
今天我們要做的就是將相關排行榜中的話題內容爬取下來當作數據素材。換句話說,我們要把頁面上排好的信息,通過代碼讀取并保存起來。
1. 爬取網頁內容
Python 爬蟲通常采用 requests 庫來處理網絡請求。這里關于 requests 的方法和參數暫不展開。
知乎熱榜
微博熱門
這里有兩點要注意:
- 我們選用的網址鏈接在未登錄狀態下也可訪問,因此 requests 方法中的參數為空也不影響。但爬蟲時更多的情況是需要登陸狀態,因此也就要求通過設置不同參數來模擬登陸去進行相關操作。
- 通過 requests 模塊獲取的網頁內容,對應的是在網站上右鍵單擊,選擇“顯示網頁源代碼”后展現的頁面。它與我們實際看到的網頁內容或者 F12 進入開發者模式中看到的網頁 elements 是不同的。前者是網絡請求后返回結果,后者是瀏覽器對頁面渲染后結果。
2. 解析爬到的內容
第一步爬到的是整個頁面內容,接下來要在所有內容中去對目標定位,然后將其讀取并保存起來。
這里我采用的是 BeautifulSoup,因為學爬蟲最先接觸這個,用起來也蠻順手。通過 BeautifulSoup 提供的方法和參數,可以很便捷定位到目標。
Beautiful Soup 是一個可以從html或XML文件中提取數據的Python庫.它能夠通過你喜歡的轉換器實現慣用的文檔導航,查找,修改文檔的方式.Beautiful Soup會幫你節省數小時甚至數天的工作時間。
Beautiful Soup 4.4.0 文檔;https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/
之前講到爬蟲所獲取的網頁對應的是網頁源代碼,那么在定位網頁中目標時可以結合網頁源代碼來制定解析策略。
這里提一點特別的,在知乎熱榜的網頁源代碼中,拉到最下方可以看到如下:
在源代碼中網頁的 script 部分,有現成的整理好的熱榜數據。所以我們為了減少工作量,直接通過 BeautifulSoup 取出 script 中內容,再用正則表達式匹配熱榜數據列表處的內容。
mport requestsimport refrom bs4 import BeautifulSoup headers={"User-Agent":"","Cookie":""}zh_url = "https://www.zhihu.com/billboard"zh_response = requests.get(zh_url,headers=headers) webcontent = zh_response.textsoup = BeautifulSoup(webcontent,"html.parser")script_text = soup.find("script",id="js-initialData").get_text()rule = r'"hotList":(.*?),"guestFeeds"'result = re.findall(rule,script_text) temp = result[0].replace("false","False").replace("true","True")hot_list = eval(temp)print(hot_list)
這里我利用了 script 中熱榜數據的列表結構,在定位取出相關字符串后,先將 js 中的 true 和 false 轉化為 Python 中的 True 和 False,最后直接通過 eval() 來將字符串轉化為直接可用的數據列表。
運行代碼結果如圖:
至于對微博熱門的解析,就是中規中矩地利用 BeautifulSoup 來對網頁元素進行定位獲取:
import requestsfrom bs4 import BeautifulSoup
url = "https://s.weibo.com/top/summary"headers={"User-Agent":"","Cookie":""}wb_response = requests.get(url,headers=headers)webcontent = wb_response.textsoup = BeautifulSoup(webcontent,"html.parser")index_list = soup.find_all("td",class_="td-01")title_list = soup.find_all("td",class_="td-02")level_list = soup.find_all("td",class_="td-03") topic_list = []for i in range(len(index_list)): item_index = index_list[i].get_text(strip = True) if item_index=="": item_index = "0" item_title = title_list[i].a.get_text(strip = True) if title_list[i].span: item_mark = title_list[i].span.get_text(strip = True) else: item_mark = "置頂" item_level = level_list[i].get_text(strip = True) 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"})print(topic_list)
通過解析,將微博熱門數據逐條存入列表中:
后續對拿到的數據加以處理展示,即可得到很多有趣的應用或實現某些功能。例如集成諸多平臺排行榜的 “今日熱榜”:
?????今日熱榜鏈接:https://tophub.today
因為并未展開爬蟲細節,今天的總結也比較簡單:
- 首先在選取要爬的網址時要給自己降低難度,例如同樣是知乎熱榜,zhihu.com/hot 需要登陸,而 zhihu.com/billboard 無需登錄便可訪問
- 解析爬取到的內容時,要結合具體頁面內容選擇最便捷的方式。當需要批量爬取相似頁面時,也要盡量整理通用的解析策略。
代碼已上傳 GitHub,鏈接如下:https://github.com/pengfexue2/hot_display.git
當然,拿到數據只是開始,后續如何去處理才是關鍵和價值所在,之后我們繼續探討。