2.5 selenium(1)
1、分析代码报错原因,
2、增加对于官方文档的了解,节点交互,动作链等功能的补充
一、介绍
Ajax加载其实是JavaScript动态渲染页面的一种情形,通过直接分析Ajax,我们仍然可以借助requests或urllib来实现数据爬取。
不过JavaScript动态渲染的页面不止Ajax这一种。比如中国青年网(详见http://news.youth.cn/gn/),它的分页部分是由JavaScript生成的,并非原始HTML代码,这其中并不包含Ajax请求。比如ECharts的官方实例(详见http://echarts.baidu.com/demo.html#bar-negative),其图形都是经过JavaScript计算之后生成的。再有淘宝这种页面,它即使是Ajax获取的数据,但是其Ajax接口含有很多加密参数,我们难以直接找出其规律,也很难直接分析Ajax来抓取。
Selenium是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(selenium remote contol)和测试的并行处理(selenium grid)。Selenium的核心selenium core基于JsUnit,完全有JavaScript编写,因此可以用于任何支持JavaScript的浏览器。
为了解决这些问题,我们可以直接使用模拟浏览器运行的方式来实现,这样就可以做到在浏览器中看到是什么样,抓取的源码就是什么样,也就是可见即可爬。这样我们就不用再去管网页内部的JavaScript用了什么算法渲染页面,不用管网页后台的Ajax接口到底有哪些参数。
Python提供了许多模拟浏览器运行的库,如Selenium、Splash、PyV8、Ghost等。
Selenium可以模拟真实浏览器,自动化测试工具(这是什么?),支持多种浏览器,爬虫中主要用来解决JavaScript渲染问题,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬。对于一些JavaScript动态渲染的页面来说,此种抓取方式非常有效。
二、基本使用
1、演示
在爬虫中,主要使用的是selenium的webdriver
from selenium import webdriver
help(webdriver) # 节选部分回复结果,显示了可支持的浏览器类型
PACKAGE CONTENTS
android (package)
blackberry (package)
chrome (package)
common (package)
edge (package)
firefox (package)
ie (package)
opera (package)
phantomjs (package)
remote (package)
safari (package)
support (package)
webkitgtk (package)示例
输出结果过长(节选)
源代码过长,在此省略。可以看到,我们得到的当前URL、Cookies和源代码都是浏览器中的真实内容。 所以说,如果用Selenium来驱动浏览器加载网页的话,就可以直接拿到JavaScript渲染的结果了,不用担心使用的是什么加密系统。(那缺点呢?)
2、声明浏览器对象
方法(*为重要的)
太多了,未完待续。。。
3、访问页面
我们可以用get()方法来请求网页,参数传入链接URL即可。比如,这里用get()方法访问淘宝,然后打印出源代码,
运行后发现,弹出了Chrome浏览器并且自动访问了淘宝,然后控制台输出了淘宝页面的源代码,随后浏览器关闭。(错误原因?)
4、查找节点
Selenium可以驱动浏览器完成各种操作,比如填充表单、模拟点击等。比如,我们想要完成向某个输入框输入文字的操作,总需要知道这个输入框在哪里吧?而Selenium提供了一系列查找节点的方法,我们可以用这些方法来获取想要的节点,以便下一步执行一些动作或者提取信息。
4.1 单个节点
比如,想要从淘宝页面中提取搜索框这个节点,首先要观察它的源代码
可以发现,它的id是q,name也是q。此外,还有许多其他属性,此时我们就可以用多种方式获取它了。比如,find_element_by_name()是根据name值获取,find_element_by_id()是根据id获取。另外,还有根据XPath、CSS选择器等获取的方式。
但输出结果正常
常用的查找元素的方法,注意只会返回符合条件的第一个元素
另外,Selenium还提供了通用方法find_element(),它需要传入两个参数:查找方式By和值。实际上,它就是find_element_by_id()这种方法的通用函数版本,比如find_element_by_id(id)就等价于find_element(By.ID, id),二者得到的结果完全一致。
4.2 多个节点
如果查找的目标在网页中只有一个,那么完全可以用find_element()方法。但如果有多个节点,再用find_element()方法查找,就只能得到第一个节点了。如果要查找所有满足条件的节点,需要用find_elements()这样的方法。
比如,要查找淘宝左侧导航条的所有条目,
结果(节选)
可以看到,得到的内容变成了列表类型,列表中的每个节点都是WebElement类型。 也就是说,如果我们用find_element()方法,只能获取匹配的第一个节点,结果是WebElement类型。如果用find_elements()方法,则结果是列表类型,列表中的每个节点是WebElement类型。
这里列出所有获取多个节点的方法:
当然,我们也可以直接用find_elements()方法来选择,
5、节点交互操作
Selenium可以驱动浏览器来执行一些操作,也就是说可以让浏览器模拟执行一些动作。比较常见的用法有:输入文字时用send_keys()方法,清空文字时用clear()方法,点击按钮时用click()方法。
下面以输入查找信息为例
这里首先驱动浏览器打开淘宝,然后用find_element_by_id()方法获取输入框,然后用send_keys()方法输入iPhone文字,等待一秒后用clear()方法清空输入框,再次调用send_keys()方法输入iPad文字,之后再用find_element_by_class_name()方法获取搜索按钮,最后调用click()方法完成搜索动作。
更多的操作可以参见官方文档的交互动作介绍:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement
6、动作链
在上面的实例中,一些交互动作都是针对某个节点执行的。比如,对于输入框,我们就调用它的输入文字和清空文字方法;对于按钮,就调用它的点击方法。其实,还有另外一些操作,它们没有特定的执行对象,比如鼠标拖曳、键盘按键等,这些动作用另一种方式来执行,那就是动作链。
比如,现在实现一个节点的拖曳操作,将某个节点从一处拖曳到另外一处,可以这样实现:
首先,打开网页中的一个拖曳实例,然后依次选中要拖曳的节点和拖曳到的目标节点,接着声明ActionChains对象并将其赋值为actions变量,然后通过调用actions变量的drag_and_drop()方法,再调用perform()方法执行动作,此时就完成了拖曳操作
更多的动作链操作可以参考官方文档:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains。
方法
7、执行JavaScript
对于某些操作,Selenium API并没有提供。比如,下拉进度条,它可以直接模拟运行JavaScript,此时使用execute_script()方法即可实现,
这里就利用execute_script()方法将进度条下拉到最底部,然后弹出alert提示框。所以说有了这个方法,基本上API没有提供的所有功能都可以用执行JavaScript的方式来实现了。
这里实际上是执行一段js代码,也就是说,你可以自己编辑一段js代码来实现某个操作,然后由execute_script命令来执行。
Last updated
Was this helpful?