1. 程式人生 > >關於爬取新浪微博,記憶體耗用過高的問題

關於爬取新浪微博,記憶體耗用過高的問題

      最近在做網際網路輿情分析時,需要爬取新浪微博做相關實驗。雖然新浪微博開放了相關輿論的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') #不載入圖片, 提升速度
    

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