上两周的时候,陈怡同学问我怎么通过程序自动化截屏浏览器页面,她说有篇论文用的是python与selenium。当时我的心理活动是这样的:“卧槽selenium是什么鬼,女博士果然是见多识广。” =。=# 然后查了一下,selenium大概可以理解成一个浏览器模拟器(或者实际上是浏览器驱动器,Selenium WebDriver),selenium提供多种编程语言的接口让我们可以通过程序来驱动本地浏览器,并执行我们想要的操作。
以陈怡同学的需求为例,就是通过python调用selenium接口来驱动我的Firefox,打开xx网站,截图保存。
我的环境:
python 2.7.6,selenium 2.48.0
安装selenium库:
参考https://pypi.python.org/pypi/selenium
#从selenium库引入webdriver类 from selenium import webdriver #新建一个browser对象(驱动firefox浏览器) browser = webdriver.Firefox() #打开news.baidu.com页面 browser.get('http://news.baidu.com/') #保存截图 browser.save_screenshot('capture.png') #关闭浏览器 browser.close()
PS:既然selenium可以驱动浏览器来干活,那么先前我做python爬虫的时候,遇到整个页面都是js动态生成的情况,我当时就束手无策了,因为之前只用过一个叫做beautiful soup的python库,他只能解析html文档,无法执行js脚本来动态更新。那么有了selenium,不就可以直接叫浏览器渲染出来页面,再将整个页面的dom交给beautiful soup嘛。
又ps:早期版本的firefox好像可以直接驱动,后面版本的需要加geckodriver,驱动chrome则需要chromedriver。
后面发现这个selenium+beautiful soup的想法其实是有完全没必要的!首先,beautiful soup对象的构造只能读取html格式的文件或字符串,如果硬要跟selenium结合起来的话,只能将selenium webdriver的page_source(页面的html源码)传递给beautiful soup,这还不如直接用urllib来的快速;其次,selenium webdriver自己就已经解析出页面的dom模型,可以通过selenium webdriver的API来定位、编辑网页元素,对页面执行各种操作,根本不用再借助其他工具。下面我们尝试一下使用selenium驱动Firefox来打开百度,并搜索selenium关键字。
from selenium import webdriver driver = webdriver.Firefox() driver.get("https://www.baidu.com") print driver.title, driver.current_url #百度首页搜索输入框的元素id='kw',搜索按钮的元素id='su' driver.find_element_by_id('kw').send_keys('selenium') driver.find_element_by_id('su').click() print driver.title, driver.current_url #driver.close()
headless browser
在上面的两个例子中我们驱动的浏览器都是Firefox,每次运行程序都会打开Firefox窗口。这在做测试的时候是很有用的,但如果只是做爬虫应用,那么每次都打开浏览器窗口并渲染网页其实是浪费时间的。所谓的headless browser是指这样一种浏览器,它没有图形化界面,主要用来做web的自动化测试以及爬虫应用。
selenium webdriver现在支持有两款headless browser:PhantomJS、HtmlUnit。
以python+selenium+phantomjs为例,改写上面百度搜索的例子:
# PhantomJS - baidu from selenium import webdriver driver = webdriver.PhantomJS() driver.set_window_size(1440, 900) driver.get("https://www.baidu.com") print driver.title, driver.current_url driver.find_element_by_id('kw').send_keys('selenium') element = driver.find_element_by_id('su') element.click() print driver.title, driver.current_url driver.quit()
注意上面代码的第5行driver.set_window_size(1440, 900),我们给无窗口浏览器phantomjs设置了窗口大小,这看起来很诡异。但如果注释掉这行的话,该程序会在后面的element.click()函数中抛出ElementNotVisibleException异常。这不知道该算是phantomjs的bug还是selenium webdriver的bug。
另外,最后一句得改为webdriver.quit()而不是webdriver.close(),否则phantomjs进程还会在后台驻留。
参考:
http://selenium-python.readthedocs.org/index.html
https://realpython.com/blog/python/headless-selenium-testing-with-python-and-phantomjs/
还有这篇中文介绍写的不错:https://wizardforcel.gitbooks.io/selenium-webdriver-simple-tutorial/content/
Pingback: python爬虫 | 哈呜.王