Selenium多种定位方式
导入模块
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver import ChromeOptions
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
初始化浏览器
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 60)
几个主要方法:
语法 | 返回值 | 说明 |
---|---|---|
text_to_be_present_in_element() | True or False | 文本存在元素 |
presence_of_element_located() | node element | 存在元素 |
element_to_be_clickable() | node element | 可点击节点 |
关于匹配
匹配页面中的文本 submit
,如果不存在则返回 -1
driver.page_source.find('submit')
关于下拉框
选择下拉框中的内容,注意只能匹配下拉框节点为 select
的节点。
- 选择到
Xpath
节点(例如下拉框中有3个选项:手機,號碼,手機號碼 - 选择 手機號碼 。
_select = Select(driver.find_element_by_xpath('xpathExparess'))
_select.select_by_visible_text('手機號碼')
关于定位节点
定位到 指定的 Xpath表达式的节点
# 方法一
driver.find_element_by_xpath('xpathExpress')
# 方法二
wait.until(EC.presence_of_element_located((By.XPATH, 'xpathExpress')))
定位到 div
节点中 并且 文本内容为 手機號碼
的节点
# 方法一
driver.find_element_by_xpath("//div[contains(text(), '手機號碼')]")
# 方法二
wait.until(EC.text_to_be_present_in_element((By.XPATH, "//div"), '手機號碼'))
定位div
节点 中 包含文本内容为 手機號碼,且 class属性为 xxx 的节点
# 方法一
driver.find_element_by_xpath('//span[contains(text(), "手機號碼") and @class="xxx"]')
# 方法二
wait.until(EC.presence_of_element_located((By.XPATH, '//div[contains(text(), "手機號碼") and @class="xxx"]')))
- 以上的三种操作足以定位到绝大多数的节点。
关于点击节点
点击节点 这一部分具体上和 定位节点 总体大同小异,区别在于后面添加了 一个
click()
点击 指定的 Xpath表达式的节点
# 方法一
driver.find_element_by_xpath('xpathExpress').click()
# 方法二
wait.until(EC.presence_of_element_located((By.XPATH, 'xpathExpress'))).click()
点击 div
节点中 并且 文本内容为 手機號碼
的节点
# 方法一
driver.find_element_by_xpath("//div[contains(text(), '手機號碼')]").click()
# 方法二
wait.until(EC.text_to_be_present_in_element((By.XPATH, "//div"), '手機號碼')).click()
点击div
节点 中 包含文本内容为 手機號碼,且 class属性为 xxx 的节点
# 方法一
driver.find_element_by_xpath('//span[contains(text(), "手機號碼") and @class="xxx"]').click()
# 方法二
wait.until(EC.presence_of_element_located((By.XPATH, '//div[contains(text(), "手機號碼") and @class="xxx"]'))).click()
点击可点击 的 Xpath节点
wait.until(EC.element_to_be_clickable((By.XPATH, 'xpathExpress'))).click()
点击可点击 的 div节点 且包含 文本内容 手機號碼
wait.until(EC.element_to_be_clickable((By.XPATH, '//div[contains(text(), "手機號碼") and @class="xxx"]'))).click()
拓展一下:
- 以上的用法可以点击到绝大多数的节点,
- 但是!!总还会有一些特别奇怪的节点,用以上的方法无法点击到节点。
总结一下用下面几种方法解决。
方法一:
- 首先获取一个节点,例如
button = wait.until(EC.element_to_be_clickable
参照 定位节点 - 然后调用 Selenium 执行 Js 的函数进行 点击。
driver.execute_script("arguments[0].click();", button)
方法二:
- 首先获取一个节点,例如
button = wait.until(EC.element_to_be_clickable
参照 定位节点 - 然后调用鼠标事件,进行点击。
ActionChains(driver).click(button).perform()
方法三:
- 首先获取需要点击的节点的 坐标,即相对于 Selenium 的x轴 和 y轴。
- 然后调用鼠标事件,进行点击。
# xoffset 和 yoffset 分别为节点坐标的 x 和 y
ActionChains(driver).move_by_offset(xoffset=x, yoffset=y).click().perform()
# 执行这一步释放鼠标,(可选
ActionChains(driver).release()
========================================================
========================================================
========================================================
关于填写内容
选择某节点,然后输入 xxx
driver.find_element_by_xpath('xpathExpress').send_keys('xxx')
wait.until(EC.presence_of_element_located((By.XPATH, 'xpathExpress'))).send_keys('xxx')
关于页面滑动
滑动页面到 指定Xpath 节点处
- 首先获取一个节点,例如
button = wait.until(EC.element_to_be_clickable
参照 定位节点 - 然后调用 Selenium 执行 Js 的函数进行 滑动页面。
driver.execute_script("arguments[0].scrollIntoView();", button)
滑动页面到最底端
- 运行即可。
driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
关于切换窗口
关于切换frame
切换到 名称 为 sunrisecai
的 frame
子页面
- 标签
id
,tag_name
也可以定位到。
driver.switch_to.frame('sunrisecai')
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'sunrisecai')))
切换到指定索引的 frame
子页面
- 切换到索引为 0 的
frame
子页面,针对不知页面的frame
子页面名称 ,比较有用。
driver.switch_to.frame(0)
wait.until(EC.frame_to_be_available_and_switch_to_it(0))
切换到
driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
无图片模式运行
options = webdriver.ChromeOptions()
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 30) # 最长等待30秒
绕过网站监测
driver.execute_script('''
event = document.createEvent('MouseEvents');
event.initEvent('mousedown', true, false);
document.querySelector("#nc_1-stage-1 > div > div.button").dispatchEvent(event);
event = document.createEvent('MouseEvents');
event.initEvent('mousemove', true, false);
Object.defineProperty(event,'clientX',{get(){return 1505;}})
document.querySelector("#nc_1-stage-1 > div > div.button").dispatchEvent(event);
''')
先分享到这,,