关于爬取新浪微博,内存耗用过高的问题

      最近在做互联网舆情分析时,需要爬取新浪微博做相关实验。虽然新浪微博开放了相关舆论的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') #不加载图片, 提升速度
    

    以上,就是我经常使用的爬虫的四种策略。

猜你喜欢

转载自blog.csdn.net/u010883226/article/details/84537513