python的浏览器“驱动”库:selenium

python的浏览器“驱动”库:selenium

上两周的时候,陈怡同学问我怎么通过程序自动化截屏浏览器页面,她说有篇论文用的是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/

One thought on “python的浏览器“驱动”库:selenium

  1. Pingback: python爬虫 | 哈呜.王

Leave a Reply

Your email address will not be published. Required fields are marked *