Python Selenium
Selenium
Selenium 是用来做自动化测试的,支持多种浏览器
在爬虫中主要用于解决 JS 渲染的问题
官方文档:https://docs.seleniumhq.org/docs/
基本使用
from selenium import webdriver
from selenium.webdriver.common.by import By
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()
try:
browser.get('https://www.baidu.com') # 发送 get 请求
search = browser.find_element_by_id('kw') # 找到搜索框
search.send_keys('Python') # 输入搜索内容
search.send_keys(Keys.ENTER) # 回车键
wait = WebDriverWait(browser, 10) # 设置等待超时时间
wait.until(EC.presence_of_element_located((By.ID, 'content_left'))) # 等到 id==content_left 标签被加载出来
print(browser.current_url)
print(browser.get_cookies())
print(browser.page_source)
finally:
browser.close()
声明浏览器对象
Selenium 支持很多浏览器,常用的
from selenium import webdriver
browser = webdriver.Chrome() # 需要安装 Chromedriver
browser = webdriver.Safari() # 需要开启设置 开发 -> 允许远程自动化
browser = webdriver.Firefox()
browser = webdriver.Ie()
browser = webdriver.Edge()
browser.close()
访问页面
通过 browser.get(url)
来访问页面
查找元素
单个元素
直接使用相应函数
from selenium import webdriver
browser = webdriver.Chrome()
browser.find_element_by_id('i1')
browser.find_element_by_xpath('//*[@id="i1"]')
browser.find_element_by_link_text('text') # 查找带超链接的文字 (全部)
browser.find_element_by_partial_link_text('text') # 查找带超链接的文字 (部分)
browser.find_element_by_name('name1')
browser.find_element_by_tag_name('a')
browser.find_element_by_class_name('c1')
browser.find_element_by_css_selector('#i1')
browser.close()
find_element
也可以使用 find_element
完成查找
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.find_element(By.ID, 'i1')
browser.close()
其他关键词
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
多个元素
和单个元素用法相同
直接使用对应函数
from selenium import webdriver
browser = webdriver.Chrome()
browser.find_elements_by_tag_name('a')
browser.close()
所有函数:
find_elements_by_id
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_name
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
find_elements
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.find_elements(By.TAG_NAME, 'a')
browser.close()
关键词与单个元素相同
获取元素信息
.get_attribute('class') # 获取属性
.text # 获取文本
.id # 获取 id
.location # 获取位置
.tag_name # 获取标签名
.size # 获取大小
交互
元素交互
在找到元素之后可以完成一些交互
send_keys('input text') # 输入
clear() # 清空输入
click() # 单击
submit() # 提交表单(不是 form 标签会报错)
动作链
通过动作链可以做到更多复杂的交互
将动作附加到动作链中串行执行
示例:
from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
browser.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
browser.switch_to.frame('iframeResult')
source = browser.find_element_by_id('draggable')
target = browser.find_element_by_id('droppable')
action = ActionChains(browser)
action.drag_and_drop(source, target)
action.perform()
执行 JS
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://www.baidu.com')
browser.execute_script('alert("Done")')
等待
隐式等待
隐式等待指没有在 DOM 中查找到相应元素时才会等待,等待一段时间后再次查找,如果没有找到会报错
通过 .implicitly_wait()
设置等待时间
from selenium import webdriver
browser = webdriver.Chrome()
browser.implicitly_wait(10)
browser.get('http://www.baidu.com')
browser.find_element_by_id('wrapper')
显式等待
等待直到某条件达成
from selenium import webdriver
from selenium.webdriver.common.by import By
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')
wait = WebDriverWait(browser, 10) # 设置超时时间
wait.until(EC.presence_of_element_located((By.ID, 'content_left'))) # 设置等待条件
browser.close()
其他常用条件
title_is # 标题是
title_contains # 标题包含
presence_of_element_located # 元素加载出,传入定位元祖,如(By.ID, 'p')
visibility_of_element_located # 元素可见
visibility_of # 可见,传入元素对象
presence_of_all_elements_located # 所有元素加载出
text_to_be_present_in_element # 某个元素文本包含某文字
text_to_be_present_in_element_value # 某个元素值包含某文字
frame_to_be_available_and_switch_to_it # frame 加载并切换
invisibility_of_element_located # 元素不可见
element_to_be_clickable # 元素可点击
staleness_of # 判断一个元素是否仍在 DOM,课判断页面是否刷新
element_to_be_selected # 元素可选择,传元素对象
element_located_to_be_selected # 元素可选择,传定位元祖
element_selection_state_to_be # 元素对象及状态是否相等
element_located_selection_state_to_be # 定位元祖及状态是否相等
alert_is_present # 是否出现 alert
操作浏览器
页面
browser.forward() # 前进
browser.back() # 后退
cookies
browser.get_cookies()
browser.delete_all_cookies()
browser.add_cookies()
选项卡
from selenium import webdriver
browser = webdriver.Chrome()
browser.get()
browser.execute_script('window.open()') # 打开一个新的选项卡
print(browser.window_handles)
browser.switch_to.window(browser.window_handles[1]) # 切换选项卡
switch to
switch_to.frame() # 切换 frame
switch_to.parent_frame()
switch_to.window() # 切换选项卡
switch_to.alert # 切换到 alert
alert.dismiss() # 关闭 alert
异常处理
示例:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
except TimeoutException:
print('Time out')
try:
browser.find_element_by_id('Foo')
except NoSuchElementException:
print('No such element')
finally:
browser.close()