關於爬取新浪微博,記憶體耗用過高的問題
最近在做網際網路輿情分析時,需要爬取新浪微博做相關實驗。雖然新浪微博開放了相關輿論的API,然而申請什麼的,並不想做,而且輿情變化快,最終還是自己爬取,相關輿情。
在用selenium的時候,有時候經常發現記憶體耗用特別高,很詫異,別人也都說selenium的速度慢等,很多缺點,甚至有時候爬蟲的速度慢的令人髮指。前兩天決定重寫爬蟲,重點解決爬蟲的速度問題。
今天終於解決了,原來是一些xpath定位不嚴謹背鍋,在爬取相關輿情的時候,我都會讓selenium習慣性的點選一下“展開全文”
圖一
正常的定位不做篩選,使得selenium對於這兩種情況都會點選,而第二種情況連結的視訊或者文章,會使得記憶體很高。而系統在執行相關的scripts的時候,會等待全部載入成功再開始執行爬取下一頁的命令。而開啟相關的這些scripts,會非常的耗時間,如果是視訊,selenium會等待視訊載入完畢,再執行下一步命令。相關篩選程式碼如下:
full_content = browser.find_elements_by_xpath('//*[@id="pl_feedlist_index"]/div[1]/div/div/div[1]/div[2]/p[1]/a/i')
full_content1 = [i for i in full_content if i.text=='c']
for i in full_content1:
i.click()
time.sleep(0.5)
print('帶有展開全文的文章的個數:','---------',len(full_content1))
既然提到selenium速度慢和其他的一些問題,就說一下我的相關的解決思路:
- 使用多執行緒爬蟲加快爬取資訊的速度,但是,對於很多的網站,需要登入的,爬蟲的速度也不是越快越好,速度越快,代表越有可能被系統識別。正常最好,和人的行為越相似,selenium被發現的機率就會越低。
- 在載入爬蟲的時候,可以選在不同的載入策略。
pageLoadStrategy設定
上面這段話的大致意思是,對於一個新載入的dom,頁面啥時候開始接受命令由頁面的載入策略決定,也就是說,我們通過修改頁面載入策略,可以使頁面即使處於載入中,也能接受我們的命令,從這點可以解決webdriver.get的阻塞問題。而每類webdriver都有一個對應的配置檔案放在特定的類DesiredCapabilities裡面,通過修改裡面的pageLoadStrategy,可以使webdriver的頁面載入策略發生改變。from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.support.ui import WebDriverWait desired_capabilities = DesiredCapabilities.CHROME # 修改頁面載入策略 desired_capabilities["pageLoadStrategy"] = "none" # 註釋這兩行會導致最後輸出結果的延遲,即等待頁面載入完成再輸出 driver = webdriver.Chrome('browsers/chromedriver.exe') wait = WebDriverWait(driver, 10) #後面可以使用wait對特定元素進行等待 driver.get('http://qzone.qq.com/') # some code to work. print("Reach end.")
上面我們可以看到,將頁面載入策略修改為none之後,頁面即使在載入過程中,程式也可以繼續執行。程式碼中的pageLoadStrategy屬性可以設定為以下三種屬性:normal
即正常情況下,selenium會等待整個介面載入完成(指對html和子資源的下載與解析,不包括ajax)
eager
要等待整個dom樹載入完成,即DOMContentLoaded這個事件完成,僅對html的內容進行下載解析
none
當html下載完成之後,不等待解析完成,selenium會直接返回
上面的程式碼用了最後一種解析方式——none,不作等待,直接返回,然後在後面的程式碼中可以用explicit_wait或者implicit_wait等方式來對特定元素進行等待捕捉,具體使用可以參考官方文件,這裡不做詳細描述。
-
設定等待時間加中斷JS 載入。
time.sleep(x) browser.execute_script('window.stop()')
-
在selenium爬取的時候根據需要載入不同的頭部檔案
-
chrome_options = Options() chrome_options.add_argument('--disable-gpu') #谷歌文件提到需要加上這個屬性來規避bug chrome_options.add_argument('--hide-scrollbars') #隱藏滾動條, 應對一些特殊頁面 chrome_options.add_argument('--headless')#無頭模式,隱藏瀏覽器 chrome_options.add_argument('blink-settings=imagesEnabled=false') #不載入圖片, 提升速度
以上,就是我經常使用的爬蟲的四種策略。