在使用selenium开发爬虫的时候,使用到了许多相关的函数和类,在这里mark一下。
查找网页中的节点
点击按钮:定位按钮
link_text、partial_link_text:主要是用来定位HTML中的<a href="url">超链接载体</a>
一般运用在超链接的定位中,但存在一个明显的缺点是超链接载体文字必须是在网页中唯一存在的,不然可能会定位不到需要的元素。
使用场景是:如果需要对百度首页中的新闻进行点击操作,该如何写脚本?——先定位到该元素,其中 新闻 两个字就是超链接的载体,因此要用到link_text。
注: link_text 是超链接载体的精确匹配,而partial_link_text是对超链接载体的模糊匹配。
延时等待
在Selenium中,get()
方法会在网页框架加载结束后结束执行,此时如果获取page_source
,可能并不是浏览器完全加载完成的页面,如果某些页面有额外的Ajax请求,我们在网页源代码中也不一定能成功获取到。
所以,在get获取到网页时需要延时等待一定时间,确保节点已经加载出来,再进行节点查找。
等待的方式分为两种:一种是隐式等待,一种是显式等待。
隐式等待
隐式等待的方式是:如果没有在DOM中找到节点,将继续等待,超出设定时间后,则抛出找不到节点的异常。或者说,当查找节点而节点并没有立即出现的时候,该方式将等待设定的时间后查找DOM,默认的时间是0。示例如下:
from selenium import webdriver
browser = webdriver.Chrome()
#设置隐式等待10s
browser.implicitly_wait(10)
browser.get('https://www.zhihu.com/explore')
input = browser.find_element_by_class_name('zu-top-add-question')
print(input)
显式等待
由于隐式等待规定了一个固定时间,而页面的加载时间又各有不同,所以它的效果可能并不是那么好。
显式等待方法在这方面要灵活很多,它首先指定要查找的节点,然后指定一个最长等待时间。如果在规定时间内加载出来了这个节点,就返回查找的节点;如果到了规定时间依然没有加载出该节点,则抛出超时异常。示例如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
# 显式等待的两个包
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
browser.get('https://www.taobao.com/')
# WebDriverWait类指定最长等待时间10s和调用频率(调用until或其他方法的间隔时间,默认是0.5秒)
wait = WebDriverWait(browser, 10, 0.5)
# 调用until方法传入要等待条件
# EC类声明所要等待的条件
input = wait.until(EC.presence_of_element_located((By.ID, 'q')))
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))
print(input, button)
presence_of_element_located
,代表节点出现的意思,其参数是节点的定位元组,也就是ID
为q
的节点搜索框。
element_to_be_clickable
,也就是可点击,所以查找按钮时查找CSS选择器为.btn-search的按钮
关于等待条件,其实还有很多,比如判断标题内容,判断某个节点内是否出现了某文字等。下表列出了所有的等待条件。
等待条件 | 含义 |
---|---|
| 标题是某内容 |
| 标题包含某内容 |
| 节点加载出来,传入定位元组,如 |
| 节点可见,传入定位元组 |
| 可见,传入节点对象 |
| 所有节点加载出来 |
| 某个节点文本包含某文字 |
| 某个节点值包含某文字 |
| 加载并切换 |
| 节点不可见 |
| 节点可点击 |
| 判断一个节点是否仍在DOM,可判断页面是否已经刷新 |
| 节点可选择,传节点对象 |
| 节点可选择,传入定位元组 |
| 传入节点对象以及状态,相等返回 |
| 传入定位元组以及状态,相等返回 |
| 是否出现警告 |
更多参考:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.support.expected_conditions。
执行JavaScript
Selenium 可以直接模拟运行JavaScript,例如下拉进度条,此时使用execute_script()
方法即可实现,代码如下:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
# 将进度条下拉到最底部
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
有了这个方法,基本上API没有提供的所有功能都可以用执行JavaScript的方式来实现了。
鼠标和键盘事件扩展