請問爬蟲如何爬取動態頁面的內容?
比如我想爬取這個話題下遊戲 - 熱門問答的內容,但是直接解析網頁只能獲取到前20個左右的回答。
我知道用Chrome瀏覽器中的檢查,點擊Network,然後往下翻,會有動態內容(JS等)刷出來,然而這個頁面刷出來的內容不像豆瓣的選電影只要改變網址中的頁碼就能獲取到相應頁碼的內容。
類似這種動態載入的頁面還有很多,希望高手能解答一下。
自問自答一下
可以用一個很牛逼的包,叫做selenium(官方文檔Selenium with Python),簡單來說就是模擬人對瀏覽器的動作,可以用代碼打開你的瀏覽器然後像人一樣操作實現瀏覽器的自動化(打開網頁、輸入文字、提交表單等),安裝等詳細介紹在官方文檔中有介紹。
以爬取這個頁面美食 - 熱門問答的所有答主信息為例,正如我描述所說,這個頁面需要將頁面滾輪往下滑才能得到更多的信息,然而requests庫好像不能實現這個功能?還是我不知道。。反正用selenium庫可以基本實現這個頁面的爬取。
話不多說直接貼代碼(環境是python3.5)首先導入需要的庫和打開知乎 - 與世界分享你的知識、經驗和見解頁面,先實現登錄。
from selenium import webdriver
import time
from bs4 import BeautifulSoup
driver=webdriver.Chrome() #用chrome瀏覽器打開
driver.get("http://www.zhihu.com") #打開知乎我們要登錄
time.sleep(2) #讓操作稍微停一下
driver.find_element_by_link_text("登錄").click() #找到『登錄』按鈕並點擊
time.sleep(2)
#找到輸入賬號的框,並自動輸入賬號 這裡要替換為你的登錄賬號
driver.find_element_by_name("account").send_keys("你的賬號")
time.sleep(2)
#密碼,這裡要替換為你的密碼
driver.find_element_by_name("password").send_keys("你的密碼")
time.sleep(2)
#輸入瀏覽器中顯示的驗證碼,這裡如果知乎讓你找煩人的倒立漢字,手動登錄一下,再停止程序,退出#瀏覽器,然後重新啟動程序,直到讓你輸入驗證碼
yanzhengma=input("驗證碼:")
driver.find_element_by_name("captcha").send_keys(yanzhengma)
#找到登錄按鈕,並點擊
driver.find_element_by_css_selector("div.button-wrapper.command &> button").click()
接著得到你登錄的cookie並載入目標頁美食 - 熱門問答,由於用這個包打開瀏覽器是不記錄你之前瀏覽器的session(cookie、書籤等),因此暫時只能用這個方法先登錄再進入目標頁。
cookie=driver.get_cookies()
time.sleep(3)
driver.get("https://www.zhihu.com/topic/19551137/hot")
time.sleep(5)
定義一個函數,實現將滾輪滑到頁面最下方的功能,這個在官方文檔中有(為了讓頁面載入完整,每5秒下移一次,一共下移10次)
def execute_times(times):
for i in range(times + 1):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5)
execute_times(10)
接下來是頁面解析,用到BeautifulSoup庫,就不多說了
html=driver.page_source
soup1=BeautifulSoup(html,"lxml")
authors=soup1.select("a.author-link")
authors_alls=[]
authors_hrefs=[]
for author in authors:
authors_alls.append(author.get_text())
authors_hrefs.append("http://www.zhihu.com"+author.get("href"))
authors_intros_urls=soup1.select("span.bio")
authors_intros=[]
for authors_intros_url in authors_intros_urls:
authors_intros.append(authors_intros_url.get_text())
for authors_all,authors_href,authors_intro in zip(authors_alls,authors_hrefs,authors_intros):
data={
"author":authors_all,
"href":authors_href,
"intro":authors_intro
}
print(data)
最後列印結果:
這裡只試了10頁的,程序沒什麼問題,不知道更多的數據會不會有問題
樓上已經有一個答案了,我來另外一個思路的吧:
還記得瀏覽器F12么?打開題主的遊戲話題頁面
注意看右邊的方法是GET
然後回到頁面,滾動到最下面,讓頁面自動刷新內容:
這個時候,調試模式中,多了一個HOT出來,這次是用的POST了,而且headers內容多了一些,其中有一條叫做:"Content-Length":"27"
我們在回到頁面滾動一頁,發現這個"Content-Length":"27"變成了"Content-Length":"28"
猜測一下是不是這個頁面意思呢?試試看嘛,反正不要錢。
代碼如下:
# -*- coding: utf-8 -*-
#!/usr/bin/env python
import requests
import json
def test():
url="https://www.zhihu.com/topic/19550994/hot"
headers = {
"Accept":"*/*",
"Accept-Encoding":"gzip, deflate, br",
"Accept-Language":"zh-CN,zh;q=0.8",
"Connection":"keep-alive",
"Content-Length":"27",
"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",
"Cookie":"這裡的內容弄你自己的吧,我就不把我的賬戶cookie信息放上來了",
"Host":"www.zhihu.com",
"Origin":"https://www.zhihu.com",
"Referer":"https://www.zhihu.com/topic/19550994/hot",
"User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
"X-Requested-With":"XMLHttpRequest",
"X-Xsrftoken":"f56ce1182d8e4ada986e83150d131a16"}
re=requests.post(url,headers = headers,data={"start":0,"offset":3047.3986818})
return json.loads(re.text)
經過測試,用27和28,確實達到了翻頁的效果,獲取到的兩次json表單,格式是一模一樣:
但是內容卻有些不同:
剩下的,你自己解析啦,都是體力活了,我休息一下。
上面的代碼可能還有一些會影響翻頁效果的,你自己多測試一下。
尤其是post過去的offset(偏移量?),你多測試一下用什麼數字最合適。
以上。
任何動態產生的內容,要麼是本地計算,要麼是從伺服器獲取的。
前者看js,後者抓包。
後者經常配上各種參數加密,不過既然瀏覽器能正確發送參數,那麼就證明肯定有辦法模擬。
如果有能力,模擬發包。如果嫌麻煩,用現成的包操作瀏覽器
這個需要抓包,模擬post或get。
請參考 python爬蟲聯想詞視頻和代碼
常常說會點擊你的f12 你就能解決90%的爬蟲問題,剩下百分之十,需要一點點腦子。。。。逃:)
效率最高的就是分析出請求數據的URL 一般都可以 而不是用selenium 沒轍的時候可以用用。
請教一個問題,我用了driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") 這個命令去載入網頁,儘管能成功,但是為什麼延遲特別長,等好久才能往下拉網頁。求指教
我想請問一下 滾輪滑到頁面最下方但是並沒有載入新內容是怎麼回事兒呢?例如YY直播的在線列表
推薦閱讀:
※如何爬網易雲音樂的評論數?
※如何開發高級Python爬蟲?
※python多線程爬蟲設計?
※學習爬蟲應該從哪裡學起?
※如何用八爪魚採集器提取新浪微博的數據呢?