最近在做互联网舆情分析时,需要爬取新浪微博做相关实验。虽然新浪微博开放了相关舆论的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') #不加载图片, 提升速度
以上,就是我经常使用的爬虫的四种策略。