Selenium攻略

转载 白月黑羽大佬的博客 + 本人对一些问题的收集

白月黑羽

个人博客
https://www.byhy.net/tut/auto/selenium/01/

Selenium 简介

https://www.bilibili.com/video/BV1Z4411o7TA/?spm_id_from=333.999.0.0&vd_source=d171c31a396363b8ea8c0e92a59cee6b

Selenium自动化环境安装

https://www.bilibili.com/video/BV1Z4411o7TA/?p=2&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

简单示例

https://www.bilibili.com/video/BV1Z4411o7TA?p=3&vd_source=d171c31a396363b8ea8c0e92a59cee6b

在不加断点的前提下, 防止程序结束
# 防止闪退
option = webdriver.ChromeOptions()
option.add_experimental_option("detach", True)
driver = webdriver.Chrome(r'F:\chromedriver.exe', options=option)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service


# 指定驱动
service = Service(r'F:\chromedriver.exe')
wd = webdriver.Chrome(service=service, )
#
wd.get('https://www.baidu.com')

# 放一个input(), 拒绝程序运行完自动结束
input()

选择元素的基本方法

https://www.bilibili.com/video/BV1Z4411o7TA?p=4&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
https://www.bilibili.com/video/BV1Z4411o7TA?p=5&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
https://www.bilibili.com/video/BV1Z4411o7TA?p=6&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
https://www.bilibili.com/video/BV1Z4411o7TA?p=8&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By


# 指定驱动
service = Service(r'F:\chromedriver.exe')
wd = webdriver.Chrome(service=service, )
# 调用webdriver对象的get方法, 打开指定网址
wd.get('https://www.byhy.net/_files/stock1.html')

# 根据id选择元素,  返回的就是改元素对应的webElement对象
ele = wd.find_element(by=By.ID, value='kw')
# 通过该webElement对象, 就可以对页面元素进行操作了
# 传入关键字到输入框
ele.send_keys('通讯\n') # \n 就相当于是回车, 或者不输入\n, 等于对element单击

ele = wd.find_element(by=By.ID, value='go')
ele.click()

pass

# 放一个input(), 拒绝程序运行完结束
input()
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By


# 指定驱动
service = Service(r'F:\chromedriver.exe')
wd = webdriver.Chrome(service=service, )
# 调用webdriver对象的get方法, 打开指定网址
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

# 根据class_name = animal, 定位到元素
eles = wd.find_elements(by=By.CLASS_NAME, value='animal')
for ele in eles:
    print(ele.text)
    
# 根据元素标签span, 定位到内容
eles = wd.find_elements(by=By.TAG_NAME, value='span')
for ele in eles:
    print(ele.text)

pass

# 放一个input(), 拒绝程序运行完结束
input()

在element内, 寻找元素

# 限制选择元素的范围是 id为container
ele = wd.find_element(by=By.ID, value='container') # type: WebElement
# 寻找container内的span
eles = ele.find_elements(by=By.TAG_NAME, value='span')
for i in eles:
    print(i.text)

selenium4 选择函数的写法

https://www.bilibili.com/video/BV1Z4411o7TA?p=7&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

等待元素出现

https://www.bilibili.com/video/BV1Z4411o7TA?p=9&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

# 后续在做`find_element`和`find_elements`操作的时候, 如果找不到元素,
# 每隔半秒钟再去界面上查看一次, 直到找到该元素, 或者过了10秒最大时长
wd.implicitly_wait(10)

wd.get('https://www.byhy.net/_files/stock1.html')

ele = wd.find_element(by=By.ID, value='kw')
ele.send_keys('通讯\n')
ele = wd.find_element(by=By.ID, value='1')
print(ele.text)

操控元素的基本方法

https://www.bilibili.com/video/BV1Z4411o7TA/?p=10&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

  • 单击 element.click()
  • 输入框 element.send_keys()
    清除原来的输入, 使用element.clear()
wd.get('https://www.byhy.net/_files/stock1.html')

ele = wd.find_element(by=By.ID, value='kw')
ele.send_keys('通讯\n')
time.sleep(1)
ele.clear()
ele.send_keys('科技\n')
  • 获取元素信息
ele = wd.find_element(by=By.ID, value='1')
print(ele.text) # 打印出网页上的 文本
print(ele.get_attribute('class')) # 打印出tag里面的class name
  • 获取整个元素对应的HTML
ele = wd.find_element(by=By.ID, value='1')
print(ele.get_attribute('outerHTML')) # 获取元素外部的HTML
print('*' * 30)
print(ele.get_attribute('innerHTML')) # 获取元素内部的HTML
  • 获取输入框里面的文字
    text无法获得在input框中已经输入的内容, 需要通过element.get_attribute(‘value’)实现
ele = wd.find_element(by=By.ID, value='kw')
ele.send_keys('hello')
print(ele.text)
print(ele.get_attribute('value'))

通过WebElement对象的 text 属性,可以获取元素 展示在界面上的 文本内容。
但是,有时候,元素的文本内容没有展示在界面上,或者没有完全完全展示在界面上。 这时,用WebElement对象的text属性,获取文本内容,就会有问题。
出现这种情况,可以尝试使用 element.get_attribute(‘innerText’) ,或者 element.get_attribute(‘textContent’)
使用 innerText 和 textContent 的区别是,前者只显示元素可见文本内容,后者显示所有内容(包括display属性为none的部分)

css表达式 - 上

https://www.bilibili.com/video/BV1Z4411o7TA/?p=11&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
https://www.bilibili.com/video/BV1Z4411o7TA/?p=12&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
https://www.bilibili.com/video/BV1Z4411o7TA/?p=13&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
https://www.bilibili.com/video/BV1Z4411o7TA/?p=14&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

根据tag, id, class选择元素

  1. 根据class定位元素 -> .
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

ele = wd.find_element(by=By.CLASS_NAME, value='plant')
ele2 = wd.find_element(by=By.CSS_SELECTOR, value='.plant') # 效果同上
print(ele.text, ele2.text)
  1. 根据tag
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

eles = wd.find_elements(by=By.CSS_SELECTOR, value='span')
for i in eles:
    print(i.get_attribute('outerHTML'))
  1. 根据id定位元素 -> #
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

ele = wd.find_element(by=By.CSS_SELECTOR, value='#searchtext')
print(ele.get_attribute('outerHTML'))

选择子元素和后代元素

  • 选择子元素
eles = wd.find_elements(by=By.CSS_SELECTOR, value='.plant > span')
for ele in eles:
    print('-------------')
    print(ele.get_attribute('outerHTML'))
  • 选择后代元素
eles = wd.find_elements(by=By.CSS_SELECTOR, value='.plant span')
for ele in eles:
    print('-------------')
    print(ele.get_attribute('outerHTML'))
  • 多重限制
eles = wd.find_elements(by=By.CSS_SELECTOR, value='#container #inner11 > span')
for ele in eles:
    print('-------------')
    print(ele.get_attribute('outerHTML'))

根据属性选择

  1. css 选择器支持通过任何属性来选择元素,语法是用一个方括号 [].
eles = wd.find_elements(by=By.CSS_SELECTOR, value='[href="http://www.miitbeian.gov.cn"]')
for ele in eles:
    print('-------------')
    print(ele.get_attribute('outerHTML'))

# 由于目标网页中只有一个href属性, 所以可以直接找href, 同上的效果
eles = wd.find_elements(by=By.CSS_SELECTOR, value='[href]')
for ele in eles:
    print('-------------')
    print(ele.get_attribute('outerHTML'))
  1. 根据 标签+属性
  • 当然,前面可以加上标签名的限制,比如 div[class=‘SKnet’] 表示 选择所有 标签名为div,且class属性值为SKnet的元素。
  1. 属性的模糊查询
  • CSS 还可以选择 属性值 包含 某个字符串 的元素, 比如, 要选择a节点,里面的href属性包含了 miitbeian 字符串,就可以这样写
eles = wd.find_elements(by=By.CSS_SELECTOR, value='a[href*="miitbeian"]')
for ele in eles:
    print('-------------')
    print(ele.get_attribute('outerHTML'))
  1. 指定开头
    • 还可以 选择 属性值 以某个字符串 开头 的元素 a[href^=“http”]
  2. 根据多个属性
    • 如果一个元素具有多个属性 CSS 选择器 可以指定 选择的元素要 同时具有多个属性的限制,像这样 div[class=misc][ctype=gun]

css表达式下

https://www.bilibili.com/video/BV1Z4411o7TA/?p=16&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
https://www.bilibili.com/video/BV1Z4411o7TA/?p=17&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
https://www.bilibili.com/video/BV1Z4411o7TA/?p=18&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
https://www.bilibili.com/video/BV1Z4411o7TA/?p=19&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

组选择

.plant , .animal

wd.get('https://cdn2.byhy.net/files/selenium/sample1a.html')

eles = wd.find_elements(by=By.CSS_SELECTOR, value='#t1 > span, #t1 p') # 选择`t1`里面所有的span和p标签
for ele in eles:
    print('-------------')
    print(ele.get_attribute('outerHTML'))

按照次序选择

  1. 父元素的第n个子节点 span:nth-child(2) -> 类型是span, 同时是父元素的第二个子结点
  2. 父元素的倒数第n个子节点 p:nth-last-child(1) -> 倒数第一个子结点类型是p
  3. 父元素的第几个某类型的子节点 span:nth-of-type(1) -> 父元素的第一个span结点
  4. 父元素的倒数第几个某类型的子节点 p:nth-last-of-type(2) -> 父元素的倒数第二个p标签
  5. 奇数节点和偶数节点 p:nth-child(even) p:nth-child(odd)
# 选择t1下的所有奇数结点
wd.get('https://cdn2.byhy.net/files/selenium/sample1a.html')

eles = wd.find_elements(by=By.CSS_SELECTOR, value='#t1 :nth-child(odd)')
for ele in eles:
    print('-------------')
    print(ele.get_attribute('outerHTML'))
# 选择t1下的p类型的偶数结点
eles = wd.find_elements(by=By.CSS_SELECTOR, value='#t1 p:nth-of-type(even)')

兄弟节点选择

  1. 相邻兄弟节点选择 -> h3 后面紧跟着的兄弟节点 span。这就是一种 相邻兄弟 关系,可以这样写 h3 + span
  2. 后续所有兄弟节点选择 -> 选择 h3 后面所有的兄弟节点 span,可以这样写 h3 ~ span

frame切换/窗口切换

https://www.bilibili.com/video/BV1Z4411o7TA/?p=20&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

如果我们要 操作 被嵌入的 html 文档 中的元素, 就必须 切换操作范围 到 被嵌入的文档中。
使用 WebDriver 对象的 switch_to 属性,像这样 wd.switch_to.frame(frame_reference)
其中, frame_reference 可以是 frame 元素的属性 name 或者 ID 。
wd.switch_to.frame('frame1'), wd.switch_to.frame('innerFrame')
也可以填写frame 所对应的 WebElement 对象
wd.switch_to.frame(wd.find_element(By.TAG_NAME, "iframe"))
如果我们已经切换到某个iframe里面进行操作了,那么后续选择和操作界面元素 就都是在这个frame里面进行的。
这时候,如果我们又需要操作 主html(我们把最外部的html称之为主html) 里面的元素了呢?
怎么切换回原来的主html呢?
很简单,写如下代码即可
wd.switch_to.default_content()

wd.get('https://cdn2.byhy.net/files/selenium/sample2.html')

# 格局iframe的id切换进入iframe
# wd.switch_to.frame('frame1')
# 根据iframe标签里面的src属性 切换进入iframe
wd.switch_to.frame(wd.find_element(by=By.CSS_SELECTOR, value='[src="sample1.html"]'))
eles = wd.find_elements(by=By.CSS_SELECTOR, value='.plant')
for ele in eles:
    print('-------------')
    print(ele.get_attribute('outerHTML'))
# 切换到外层html
wd.switch_to.default_content()
# 打印外部的element
ele = wd.find_element(by=By.ID, value='outerbutton')
print(ele)

切换到新窗口

https://www.bilibili.com/video/BV1Z4411o7TA/?p=21&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

可以使用Webdriver对象的switch_to属性的 window方法
wd.switch_to.window(handle)
其中,参数handle需要传入什么呢?
WebDriver对象有window_handles 属性,这是一个列表对象, 里面包括了当前浏览器里面所有的窗口句柄。

# 获得所有窗口的句柄, 遍历每一个句柄, 根据title属性来判断并进入该窗口句柄
for handle in wd.window_handles:
    # 先切换到该窗口
    wd.switch_to.window(handle)
    # 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口
    if 'Bing' in wd.title:
        # 如果是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环,
        break

为了保留原来的句柄变量

# mainWindow变量保存当前窗口的句柄
mainWindow = wd.current_window_handle
# 通过前面保存的老窗口的句柄,自己切换到老窗口
wd.switch_to.window(mainWindow)

实例

wd.get('https://www.byhy.net/tut/auto/selenium/frame/')

ele = wd.find_element(by=By.CSS_SELECTOR, value='a[href="https://cdn2.byhy.net/files/selenium/sample3.html"]')
ele.click()

# 如果后续还需要切换到主窗口操作, 可以先将window句柄保存下来
main_window_handle = wd.current_window_handle
# 通过handle的检查, 进入`白月黑羽的测试网页`窗口, 进行操作
for handle in wd.window_handles:
    wd.switch_to.window(handle)
    if '白月黑羽测试网页' in wd.title:
        break
# 获得这个窗口的句柄
main_window_handle_2 = wd.current_window_handle
ele = wd.find_element(by=By.CSS_SELECTOR, value='a[href="http://www.bing.com"')
ele.click()
# 进入`Bing`的网页, 进行操作
for handle in wd.window_handles:
    wd.switch_to.window(handle)
    if 'Bing' in wd.title:
        break
ele = wd.find_element(by=By.CSS_SELECTOR, value='#sb_form_q')
ele.send_keys('hello world\n')

# 切换会原来的window handle
wd.switch_to.window(main_window_handle_2)
ele = wd.find_element(by=By.CSS_SELECTOR, value='#outerbutton')
ele.click()

pass

选择框

https://www.bilibili.com/video/BV1Z4411o7TA/?p=22&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

radio框

# 获取当前选中的元素
element = wd.find_element(By.CSS_SELECTOR, 
  '#s_radio input[checked=checked]')
print('当前选中的是: ' + element.get_attribute('value'))

# 点选 小雷老师
wd.find_element(By.CSS_SELECTOR, 
  '#s_radio input[value="小雷老师"]').click()

checkbox框

# 如何勾选小雷老师
wd.get('https://cdn2.byhy.net/files/selenium/test2.html')
# 先将原来已经被选中的checkbox, 取消勾选
eles = wd.find_elements(by=By.CSS_SELECTOR, value='#s_checkbox input[checked=checked]')
for ele in eles:
    ele.click()
# 在选一下小雷老师
ele = wd.find_element(by=By.CSS_SELECTOR, value='#s_checkbox input[value="小雷老师"]')
ele.click()

select框

https://www.bilibili.com/video/BV1Z4411o7TA/?p=24&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

博客内容

https://www.byhy.net/tut/auto/selenium/skills_1/

非select的下拉框, 定位&选择技巧

博客地址

https://blog.csdn.net/qsmy_an/article/details/126226992

1.问题:
遇到一个下拉框,表面显示"请选择",但是点击后下拉列表出来了同时还可以输入选择。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2CBVbrgA-1671531102515)(2022-12-20-15-57-08.png)]
既不是select也没有iframe框。
2.分析,需要四步:
①先定位[社区名称]这个框;
②调出下拉列表;
③选择某个下拉值;
④点击该值;
3.实际操作
①定位这个框,定位方法很多,大家择需选择就可以,我经常用xpath;
xpath不管是觉得路径还是相对路径,无所谓好坏,能解决了问题就可以。有些元素吧,确实不好定位啊。
②用键盘向下键,调出下拉框;
③把要选择的值标红显示;
④js点击操作;

# 代码如下:
#红色框线定位[社区名称]
ele6 = self.driver. \
    find_element_by_xpath(
    'XXXXX'
)
self.driver.execute_script(
    "arguments[0].setAttribute('style',arguments[1]);",
    ele6,
    "border:2px solid red;"
)
time.sleep(1)
#按向下键调起下拉列表
ele6.send_keys(Keys.ARROW_DOWN)
time.sleep(1)
#给要选择的值标红框
ele7 = self.driver.find_element_by_xpath(
    'XXXXXX'
)
self.driver.execute_script(
    "arguments[0].setAttribute('style',arguments[1]);",
    ele7,
    "border:2px solid red;"
)
time.sleep(1)
#点击:[1000076|测试001]这个选项
xp = 'XXXXXXX'
button = self.driver.find_element_by_xpath(xp)
self.driver.execute_script("arguments[0].click();",button)
time.sleep(1)

实战技巧

博客内容

https://www.byhy.net/tut/auto/selenium/skills_2/

ActionChain

https://www.bilibili.com/video/BV1Z4411o7TA/?p=25&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

冻结页面

https://www.bilibili.com/video/BV1Z4411o7TA/?p=26&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

弹出对话框

https://www.bilibili.com/video/BV1Z4411o7TA/?p=27&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

Alert

Confirm

Prompt

其他技巧

窗口大小

获取当前窗口标题

获取当前窗口URL地址

截屏

手机模式

上传文件

自动化Edge浏览器


Xpath选择器

博客地址: https://www.byhy.net/tut/auto/selenium/xpath_1/

Xpath语法简介

https://www.bilibili.com/video/BV1Z4411o7TA?p=28&vd_source=d171c31a396363b8ea8c0e92a59cee6b

绝对路径选择

从根节点开始的,到某个节点,每层都依次写下来,每层之间用 / 分隔的表达式,就是某元素的 绝对路径
上面的xpath表达式 /html/body/div ,就是一个绝对路径的xpath表达式, 等价于 css表达式 html>body>div
自动化程序要使用Xpath来选择web元素,应该调用 WebDriver对象的方法 find_element_by_xpath 或者 find_elements_by_xpath,像这样:
elements = driver.find_elements(By.XPATH, "/html/body/div")

相对路径选择

有的时候,我们需要选择网页中某个元素, 不管它在什么位置 。
比如,选择示例页面的所有标签名为 div 的元素,如果使用css表达式,直接写一个 div 就行了。
那xpath怎么实现同样的功能呢? xpath需要前面加 // , 表示从当前节点往下寻找所有的后代元素,不管它在什么位置。
所以xpath表达式,应该这样写: //div
‘//’ 符号也可以继续加在后面,比如,要选择 所有的 div 元素里面的 所有的 p 元素 ,不管div 在什么位置,也不管p元素在div下面的什么位置,则可以这样写 //div//p
对应的自动化程序如下
elements = driver.find_elements(By.XPATH, "//div//p")
如果使用CSS选择器,对应代码如下
elements = driver.find_elements(By.CSS_SELECTOR,"div p")
如果,要选择 所有的 div 元素里面的 直接子节点 p , xpath,就应该这样写了 //div/p
如果使用CSS选择器,则为 div > p

通配符

如果要选择所有div节点的所有直接子节点,可以使用表达式 //div/*

  • 是一个通配符,对应任意节点名的元素,等价于CSS选择器 div > *
    代码如下:
elements = driver.find_elements(By.XPATH, "//div/*")
for element in elements:
    print(element.get_attribute('outerHTML'))

根据属性选择

https://www.bilibili.com/video/BV1Z4411o7TA/?p=29&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b
Xpath 可以根据属性来选择元素。
根据属性来选择元素 是通过 这种格式来的 [@属性名=‘属性值’]
注意:
属性名注意前面有个@
属性值一定要用引号, 可以是单引号,也可以是双引号

根据id属性选择

选择 id 为 west 的元素,可以这样 //*[@id=‘west’]

根据class属性选择

选择所有 select 元素中 class为 single_choice 的元素,可以这样 //select[@class=‘single_choice’]
如果一个元素class 有多个,比如

<p id="beijing" class='capital huge-city'>
    北京    
</p>

如果要选 它, 对应的 xpath 就应该是 //p[@class=“capital huge-city”]
不能只写一个属性,像这样 //p[@class=“capital”] 则不行

根据其他属性

同样的道理,我们也可以利用其它的属性选择
比如选择 具有multiple属性的所有页面元素 ,可以这样 //*[@multiple]

属性值包含字符串

要选择 style属性值 包含 color 字符串的 页面元素 ,可以这样 //[contains(@style,‘color’)]
要选择 style属性值 以 color 字符串 开头 的 页面元素 ,可以这样 //
[starts-with(@style,‘color’)]
要选择 style属性值 以 某个 字符串 结尾 的 页面元素 ,大家可以推测是 //*[ends-with(@style,‘color’)], 但是,很遗憾,这是xpath 2.0 的语法 ,目前浏览器都不支持

按次序选择

https://www.bilibili.com/video/BV1Z4411o7TA/?p=30&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

某类型 第几个 子元素

比如
要选择 p类型第2个的子元素,就是
//p[2]
注意,选择的是 p类型第2个的子元素 , 不是 第2个子元素,并且是p类型 。
注意体会区别
再比如,要选取父元素为div 中的 p类型 第2个 子元素
//div/p[2]

第几个子元素

也可以选择第2个子元素,不管是什么类型,采用通配符
比如 选择父元素为div的第2个子元素,不管是什么类型
//div/*[2]

某类型 倒数第几个 子元素

当然也可以选取倒数第几个子元素
比如:
选取p类型倒数第1个子元素
//p[last()]
选取p类型倒数第2个子元素
//p[last()-1]
选择父元素为div中p类型倒数第3个子元素
//div/p[last()-2]

范围选择

xpath还可以选择子元素的次序范围。
比如,
选取option类型第1到2个子元素
//option[position()<=2]
或者
//option[position()<3]
选择class属性为multi_choice的前3个子元素
//*[@class='multi_choice']/*[position()<=3]
选择class属性为multi_choice的后3个子元素
//*[@class='multi_choice']/*[position()>=last()-2]
为什么不是 last()-3 呢? 因为
last() 本身代表最后一个元素
last()-1 本身代表倒数第2个元素
last()-2 本身代表倒数第3个元素

组选择、父节点、兄弟节点

https://www.bilibili.com/video/BV1Z4411o7TA?p=31&vd_source=d171c31a396363b8ea8c0e92a59cee6b

组选择

css有组选择,可以同时使用多个表达式,多个表达式选择的结果都是要选择的元素
css 组选择,表达式之间用 逗号 隔开
xpath也有组选择, 是用 竖线 隔开多个表达式
比如,要选所有的option元素 和所有的 h4 元素,可以使用
//option | //h4
等同于CSS选择器
option , h4
再比如,要选所有的 class 为 single_choice 和 class 为 multi_choice 的元素,可以使用
//*[@class='single_choice'] | //*[@class='multi_choice']
等同于CSS选择器
.single_choice , .multi_choice

选择父节点

xpath可以选择父节点, 这是css做不到的。
某个元素的父节点用 /.. 表示
比如,要选择 id 为 china 的节点的父节点,可以这样写 //*[@id='china']/..
当某个元素没有特征可以直接选择,但是它有子节点有特征, 就可以采用这种方法,先选择子节点,再指定父节点。
还可以继续找上层父节点,比如 //*[@id='china']/../../..

兄弟节点选择

前面学过 css选择器,要选择某个节点的后续兄弟节点,用 波浪线
xpath也可以选择 后续 兄弟节点,用这样的语法 following-sibling::
比如,要选择 class 为 single_choice 的元素的所有后续兄弟节点 //*[@class='single_choice']/following-sibling::*
等同于CSS选择器 .single_choice ~ *
如果,要选择后续节点中的div节点, 就应该这样写 //*[@class='single_choice']/following-sibling::div
xpath还可以选择 前面的 兄弟节点,用这样的语法 preceding-sibling::
比如,要选择 class 为 single_choice 的元素的所有前面的兄弟节点 //*[@class='single_choice']/preceding-sibling::*
而CSS选择器目前还没有方法选择前面的 兄弟节点

通过文本内容定位元素

from selenium.webdriver.common.by import By

# 方式1:通过文本内容精准定位元素
driver.find_element(By.XPATH, '//div[text()="文本内容"]')   

# 方式2:通过文本内容模糊定位元素
driver.find_element(By.XPATH, '//div[contains(text(), "文本内容")]')

selenium 注意点

https://www.bilibili.com/video/BV1Z4411o7TA?p=32&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

我们来看一个例子
我们的代码:
先选择示例网页中,id是china的元素
然后通过这个元素的WebElement对象,使用find_elements_by_xpath,选择里面的p元素,

# 先寻找id是china的元素
china = wd.find_element(By.ID, 'china')
# 再选择该元素内部的p元素
elements = china.find_elements(By.XPATH, '//p')
# 打印结果
for element in elements:
    print('----------------')
    print(element.get_attribute('outerHTML'))

运行发现,打印的 不仅仅是 china内部的p元素, 而是所有的p元素。
要在某个元素内部使用xpath选择元素, 需要 在xpath表达式最前面加个点 。
像这样
elements = china.find_elements(By.XPATH, './/p')
当然也可以一步直接写完
//*[@id='china']/p
这个问题只有xpath有, CSS没有这个问题

selenium自动化EDGE浏览器

https://www.bilibili.com/video/BV1Z4411o7TA?p=33&spm_id_from=pageDriver&vd_source=d171c31a396363b8ea8c0e92a59cee6b

Xpath click点击无效怎么办

https://blog.csdn.net/Beyond_F4/article/details/111615170

通过CSS定位, 通过JS执行

js = 'document.querySelector("#login-form > div.fm-btn > button").click();'
self.chrome.execute_script(js)

python selenium设置chrome的下载路径

https://www.cnblogs.com/linwenbin/p/10361986.html

from selenium import webdriver
import time

def set_chrome_pref():
    chromeOptions = webdriver.ChromeOptions()
    prefs = {"download.default_directory":"D:\"}
    chromeOptions.add_experimental_option("prefs", prefs)
    driver = webdriver.Chrome(chrome_options=chromeOptions)
    time.sleep(10)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值