關於爬取新浪微博,內存耗用過高的問題

      最近在做互聯網輿情分析時,需要爬取新浪微博做相關實驗。雖然新浪微博開放了相關輿論的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速度慢和其他的一些問題,就說一下我的相關的解決思路:

  1. 使用多線程爬蟲加快爬取信息的速度,但是,對於很多的網站,需要登錄的,爬蟲的速度也不是越快越好,速度越快,代表越有可能被系統識別。正常最好,和人的行爲越相似,selenium被發現的機率就會越低。
  2. 在加載爬蟲的時候,可以選在不同的加載策略。

    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等方式來對特定元素進行等待捕捉,具體使用可以參考官方文檔,這裏不做詳細描述。

  3. 設置等待時間加中斷JS 加載。

    time.sleep(x)
    browser.execute_script('window.stop()') 

     

  4. 在selenium爬取的時候根據需要加載不同的頭部文件

  5. 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') #不加載圖片, 提升速度
    

    以上,就是我經常使用的爬蟲的四種策略。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章