引子
现在的网站有很多都是动态加载的,这种网页用之前我们熟悉的BeautifulSoup与Requests工具是很难完成的。“动态加载”是啥意思呢,我就不用专业术语解释了(毕竟我不是专业人士),简单直白来说,就是需要鼠标点击,或者键盘操作才能完成的,例如按下键盘左右键,网页上面的图片就翻页咯,很多图库网站都是这样做的。在举例,有的网页是这样的,刚开始加载完之后,并不显示内容,而是过2秒之后,才加载出网页的主要内容,当然,中间会有过场gif,让读者不至于太无聊。如果你要爬取的网页是这种动态加载的网页,那就很麻烦,目前的解决方案有两个,第一,分析网页的源代码,主要是那些JavaScript的代码,找到最终你想要的资源的链接是指向哪里的,然后用老办法BeautifulSoup与Requests就可以解决了,但是分析代码的过程很麻烦,主要是因为JavaScript代码为了让你难以分析,通常都在上线之前把所有注释去掉,并且很多JavaScript代码本身非常冗余复杂,更增加了爬虫的难度。第二个方法就是今天介绍的,主要使用selenium与PhantomJS来解决,网页不是需要你点击么,那就模拟点击,最终获取到网页最终形态的代码,在分析你需要的资源就可以了。整个想法都是简单粗暴,但是呢爬取的过程因为需要模拟真正的网页渲染过程,所以通常速度很慢。
简介
selenium与PhantomJS具体是啥呢?有这么神奇吗?
先说PhantomJS,这货本质上是一个没有界面的浏览器,类似chrome和Firefox,你可能奇怪,没有界面那用它做什么?虽然没有界面,但可以获取网页内容,具体就是获取html的内容,那就可以拿给BeautifulSoup进行分析,获取链接或其他资源。而且,强大的是,这个浏览器也可以实现点击,模拟键盘输入等功能,具体怎么实现,稍后介绍。
那么selenium是啥呢?selenium主业并不是用来做爬虫的,是用来做自动化测试的。自动化测试就是有些大公司的网站要实现很重要而且很多的功能,功能失效后果会很严重,用人来进行测试太慢,于是发明了selenium,模拟人的操作,实现自动化的测试网站功能,现在你明白了么,selenium就相当于模拟了你的双手,进行点击或输入。人类发明计算机最初的愿望就是解放自己的双手,至于空闲的双手用来干嘛,那就O(∩_∩)O~。所以selenium可以操作浏览器,事实上,selenium不仅可以操作PhantomJS这款浏览器,现在主流的浏览器它都可以操作,只要提前安装好驱动就可以了。
部署
selenium的安装主要过程,建议参考文档进行。由于selenium支持多种语言,java、python、Nodejs、Ruby等。仅用Python作为例子,文档在此
命令是:
pip install selenium
Phantom的部署需要根据你用的操作系统来分别用不同的方法进行部署,英文文档在此(没有找到中文文档,欢迎留言)
以windows为例,需要下载一个phantomjs.exe文件,并且将指向这个文件的路径写进代码中就可以了。
方法
具体的东西,在文档中写的很详细,但文档一般是用Firefox作为例子写的,将Firefox换成PhantomJS大多数情况没问题。
应用举例
这个例子是文档中的,后面有机会我把自己做的一些小代码放进来。这里之所以用Firefox是因为,firefox会把网页打开,让你看到网页发生了什么变化,而如果直接用PhantomJS,也可以实现相同的功能,但仅仅显示一个漆黑的命令行,你不会知道发生了什么。如果充分理解了firefox的例子,把他替换为PhantomJS也可以实现相同的功能。
from selenium import webdriver from selenium.webdriver.common.keys import Keys driver = webdriver.Firefox() driver.get("http://www.python.org") assert "Python" in driver.title elem = driver.find_element_by_name("q") elem.clear() elem.send_keys("pycon") elem.send_keys(Keys.RETURN) assert "No results found." not in driver.page_source driver.close()
selenium.webdriver 模块提供了所有WebDriver的实现, 当前支持的WebDriver有: Firefox, Chrome, IE and Remote,PhantomJS。 `Keys`类提供键盘按键的支持,比如:RETURN, F1, ALT等
from selenium import webdriver from selenium.webdriver.common.keys import Keys
接下来,创建一个Firefox WebDriver的实例
driver = webdriver.Firefox()
driver.get 方法将打开URL中填写的地址,WebDriver 将等待, 直到页面完全加载完毕(其实是等到”onload” 方法执行完毕),然后返回继续执行你的脚本。 值得注意的是,如果你的页面使用了大量的Ajax加载, WebDriver可能不知道什么时候页面已经完全加载:
driver.get("http://www.python.org")
下一行是用assert的方式确认标题是否包含“Python”一词。 (译注:assert 语句将会在之后的语句返回false后抛出异常,详细内容可以自行百度)
assert "Python" in driver.title
WebDriver 提供了大量的方法让你去查询页面中的元素,这些方法形如: find_element_by_*。 例如:包含 name 属性的input输入框可以通过 find_element_by_name 方法查找到, 详细的查找方法可以在第四节元素查找中查看:
elem = driver.find_element_by_name("q")
接下来,我们发送了一个关键字,这个方法的作用类似于你用键盘输入关键字。 特殊的按键可以使用Keys类来输入,该类继承自 selenium.webdriver.common.keys, 为了安全起见,我们先清除input输入框中的任何预填充的文本(例如:”Search”),从而避免我们的搜索结果受影响:
elem.clear() elem.send_keys("pycon") elem.send_keys(Keys.RETURN)
提交页面后,你会得到所有的结果。为了确保某些特定的结果被找到,使用assert 如下:
assert "No results found." not in driver.page_source
最后,关闭浏览器窗口,你还可以使用quit方法代替close方法, quit将关闭整个浏览器,而_close——只会关闭一个标签页, 如果你只打开了一个标签页,大多数浏览器的默认行为是关闭浏览器:
driver.close()
厉害了,感谢分享!