介绍
selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题。
selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器。
浏览器驱动1
2
3
4
5
6from selenium import webdriver
browser=webdriver.Chrome()
browser=webdriver.Firefox()
browser=webdriver.PhantomJS()
browser=webdriver.Safari()
browser=webdriver.Edge()
安装
selenium + chromedriver 有界面
安装:
- pip3 install selenium
- 下载chromdriver.exe放到python安装路径的scripts目录中即可
验证安装:
1 | from selenium import webdriver |
selenium+phantomjs 无界面
安装:
- pip3 install selenium
- 下载phantomjs,解压后把phantomjs.exe所在的bin目录放到环境变量
下载链接:http://phantomjs.org/download.html
验证安装:
1 | from selenium import webdriver |
基本使用
1 | from selenium import webdriver |
三种选择器
1 | from selenium import webdriver |
获取标签属性
1 | from selenium import webdriver |
等待元素被加载
- selenium只是模拟浏览器的行为,而浏览器解析页面是需要时间的(执行css,js),一些元素可能需要过一段时间才能加载出来,为了保证能查找到元素,必须等待
- 等待的方式分两种:
- 隐式等待:在browser.get(’xxx’)前就设置,针对所有元素有效
- 显式等待:在browser.get(’xxx’)之后设置,只针对某个元素有效
隐式等待1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19from selenium import webdriver
from selenium.webdriver.common.keys import Keys # 键盘按键操作
browser = webdriver.Chrome()
# 隐式等待:在查找所有元素时,如果尚未被加载,则等10秒
browser.implicitly_wait(10)
browser.get('https://www.baidu.com')
input_tag = browser.find_element_by_id('kw')
input_tag.send_keys('美女')
input_tag.send_keys(Keys.ENTER)
contents = browser.find_element_by_id('content_left') # 没有等待环节而直接查找,找不到则会报错
print(contents)
browser.close()
显示等待1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22from selenium import webdriver
from selenium.webdriver.common.by import By # 按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys # 键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait # 等待页面加载某些元素
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
input_tag = browser.find_element_by_id('kw')
input_tag.send_keys('美女')
input_tag.send_keys(Keys.ENTER)
# 显式等待:显式地等待某个元素被加载
wait = WebDriverWait(browser, 10)
wait.until(EC.presence_of_element_located((By.ID, 'content_left')))
contents = browser.find_element(By.CSS_SELECTOR, '#content_left')
print(contents)
browser.close()
元素交互操作
点击.click() 清空.clear()
1 | from selenium import webdriver |
动作链 Action Chains
官网解释1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
browser.switch_to.frame('iframeResult') # 切换到iframeResult
source = browser.find_element_by_id('draggable')
target = browser.find_element_by_id('droppable')
actions = ActionChains(browser) # 拿到动作链对象
# drag_and_drop 拖放
actions.drag_and_drop(source, target) # 把动作放到动作链中,准备串行执行
actions.perform() # 执行
# browser.close()
执行JS
在交互动作比较难实现的时候可以自己写JS(万能方法)1
2
3
4
5
6
7
8
9
10from selenium import webdriver
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
browser.execute_script('alert("hello world")') # 打印警告
finally:
# browser.close()
pass
iframe元素的切换
frame相当于一个单独的网页,在父frame里是无法直接查看到子frame的元素的,必须switch_to_frame切到该frame下,才能进一步查找.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19from selenium import webdriver
browser = webdriver.Chrome()
try:
browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
browser.switch_to.frame('iframeResult') # 切换到id为iframeResult的frame
tag1 = browser.find_element_by_id('droppable')
print(tag1)
# tag2=browser.find_element_by_id('textareaCode') #报错,在子frame里无法查看到父frame的元素
browser.switch_to.parent_frame() # 切回父frame,就可以查找到了
tag2 = browser.find_element_by_id('textareaCode')
print(tag2)
finally:
browser.close()
其他
模拟浏览器的前进后退
1 | import time |
cookies
1 | from selenium import webdriver |
选项卡管理
切换选项卡,有js的方式windows.open,有windows快捷键:ctrl+t等,最通用的就是js的方式
1 | import time |
异常处理
1 | from selenium import webdriver |