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()
原文地址:https://www.cnblogs.com/dbf-/p/11436050.html