做爬虫只做静态是远远不够的,特别是现在动态页面越来越多了,selenium 基本上是必备的库了,虽然人家开发这个的初衷是做测试用的。
安装
主要安装两部分,一个是 selenium 这个库,不必再说。还有就是 webdriver。
如果看网上的各种教程,基本用的是 phantomJS 的比较多,然而如果关注新闻的话,你会记得前段时间 PhantomJS 被 selenium 抛弃了。于是我就去用 headless chrome 了(firefox: ???)
以 headless chrome 为例,肯定首先得装一下 chrome, 然后要下载一个 chromedriver
小坑
别用太旧的版本
我服务器上的 python-selenium 还是 2.x 的版本,着实坑了我一把,get_elements 的时候各种莫名其妙 json 解析错误,更新 3.11 之后,一切正常,虽然 PhantomJS 不让用了。
PhantomJS 的废弃
正如上文提到的,这是前几个月的一个大新闻。最好还是尽量避免吧。
等待加载
如果 webdriver.get(url)
之后立刻就拿出来 html 处理,你会发现得到的 html 和 F12 看到的不太一样,这是因为有些动态加载的东西还没有完成。最简单的处理方法是 time.sleep
, 但是无法确定等待的具体时间。
可以这样:
from selenium.webdriver.support.wait import WebDriverWait
WebDriverWait(driver, 15).until(lambda x: x.find_elements_by_class_name('ftrH'))
15 是最长等待时间,默认 0.5 秒查看一次,后面的表达式是条件,比如可以监视一下某一个 class 对应的元素有没有加载好。
栗子
下面是一个非常简单的用 selenium 提取 bing 搜索结果 url 的小栗子, 一看就懂。
如果直接静态爬中文 bing 的东西,嘿嘿,你会发现只能爬到一堆广告和无关页面。
因为我的服务器没有 GUI,因此用了 pyvirtualdisplay
这个库来模拟。
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from pyvirtualdisplay import Display
keyword = '关键词'
page = 0
url = 'https://www4.bing.com/search?q={}&first={}'.format(keyword, page*10 + 1)
print(url)
with Display(backend='xvfb', size=(800, 600)):
driver = webdriver.Chrome(executable_path='./chromedriver')
driver.get(url)
WebDriverWait(driver, 15).until(lambda x: x.find_elements_by_class_name('ftrH'))
tt = driver.find_elements_by_xpath('//h2/a')
for t in tt:
print(t.get_attribute('href'))
driver.quit()