目录
内容大纲
- id定位
- class_name定位
- tag_name定位
- name定位
- LINK_TEXT定位
- CSS_SELECTOR定位
- XPATH定位
一、前置知识
python基础语法
HTML-CSS-JS
二、id定位
注意:
id一般来说是唯一的,如果有重复的id,网页可以展示,但是JS会报错。一般来说只有第一个jd是有效的。
案例
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
Driver = webdriver.Firefox()
Driver.maximize_window() # 窗口最大化
Driver.get("https://www.baidu.com/index.php?tn=monline_3_dg")
# input
Driver.find_element(By.ID, "kw").send_keys("舞蹈")
time.sleep(2)
# button “百度一下”
Driver.find_element(By.ID, "su").click()
# close
Driver.quit()
三、class_name定位
注意 CSS中可能有多个重复的class_name。
1. 唯一的class_name
# coding=gb2312
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
Driver = webdriver.Firefox()
Driver.maximize_window() # 窗口最大化
Driver.get("https://www.bilibili.com/")
Driver.find_element(By.CLASS_NAME, "nav-search-input").send_keys("舞蹈")
time.sleep(2)
Driver.find_element(By.CLASS_NAME, "nav-search-btn").click()
2. 不唯一的class_name
第一行代码默认点击第一个元素。第二行代码点击第五个对应的元素。
Driver.find_element(By.CLASS_NAME, "channel-link").click() # click first element
Driver.find_elements(By.CLASS_NAME, "channel-link")[4].click() # click five element
输出里面的元素:
四、 tag_name定位(标签定位)
- 查询标签是否唯一
- 标签唯一
Driver.find_element(By.TAG_NAME, "input").send_keys("舞蹈")
五、name 定位
一般在表单元素会出现。
-
查询标签是否唯一
-
标签唯一
Driver.find_element(By.NAME, "wd").send_keys("舞蹈")
Driver.find_elements(By.NAME, "wd")[0].send_keys("舞蹈")
六、LINK_TEXT定位
如下图所示,含有href链接
准确匹配
- 查询标签是否唯一
Ctrl+F 搜索百度。(这里注意的是,包含“百度”这个词的不算)
2.点击”新闻“标签
Driver.find_element(By.LINK_TEXT, "新闻").click()
文本模糊匹配
- 当前的链接是要包含“新闻"两个字的。这里的标签就不在唯一。因此,这里直接用下标找到”新闻“标签。
- 只能查询到可点击的标签。
Driver.find_elements(By.PARTIAL_LINK_TEXT, "新闻")[0].click()
七、 CSS_SELECTOR定位
定位复杂元素。
# coding=gb2312
# CSS
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
Driver = webdriver.Firefox()
Driver.maximize_window() # 窗口最大化
Driver.get("https://www.baidu.com/")
# 根据id定位,前面要加井号(CSS格式)
#Driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("百度")
# 根据class属性值定位,前面加”.“
#Driver.find_element(By.CSS_SELECTOR, ".s_ipt").send_keys("百度")
# 根据name属性值定位,前面加”[name=' '] “
#Driver.find_element(By.CSS_SELECTOR, "[name='wd']").send_keys("百度")
# 根据标签属性定位,前面加"a[href=' ']"
#Driver.find_element(By.CSS_SELECTOR, "a[href='http://news.baidu.com']").click()
# 模糊匹配,前面加”a[href*=' ']"
#Driver.find_element(By.CSS_SELECTOR, "a[href*='news.baidu']").click()
# 模糊匹配-匹配开头,前面加”a[href^=' ']"
#Driver.find_element(By.CSS_SELECTOR, "a[href^='http://news']").click()
# 模糊匹配-匹配结尾,前面加”a[href$=' ']"
#Driver.find_element(By.CSS_SELECTOR, "a[href$='news.baidu.com']").click()
# 组合定位,input+class,"input.class_name"
#Driver.find_element(By.CSS_SELECTOR, "input.s_ipt").send_keys("百度")
# 父子关系,div>a
# 多个class_name
#Driver.find_element(By.CSS_SELECTOR, "span.s_ipt_wr.new-pmd.quickdelete-wrap>input").send_keys("百度")
# 第一个标签,div>a:first-child
#Driver.find_element(By.CSS_SELECTOR, "div#s-top-left>a:first-child").click()
# Driver.find_elements(By.CSS_SELECTOR, "div#s-top-left>a")[0].click() # 注意这里下标是0
# 顺序标签,div>a:nth-child(1),下标从1开始
# Driver.find_element(By.CSS_SELECTOR, "div#s-top-left>a:nth-child(1)").click()# 注意这里下标是1
# 后代关系,找到div下面的所有的a标签, div a(中间是空格号)
# 可以直接copy selector(有些易读性会比较差)
Driver.find_element(By.CSS_SELECTOR, "a.mnav:nth-child(4)").click()# 注意这里下标是1
time.sleep(2)
# close
Driver.quit()
八、XPATH定位
# coding=gb2312
# XPATH
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
Driver = webdriver.Firefox()
Driver.maximize_window() # 窗口最大化
Driver.get("https://www.baidu.com/")
# 绝对路径(一般不推荐) /一个斜杠;下标定位a[4]。
# 点击“百度”
# Driver.find_element(By.XPATH,"/html/body/div[@id='wrapper']/div[@id='head']/div[@id='s-top-left']/a[1]").click()
# 相对路径+组合定位 //,两个斜杠
# 1. 根据id,class,name定位。//input[@class=' ']
#Driver.find_element(By.XPATH, "//input[@class='s_ipt']").send_keys("新闻")
# 2. 多个属性组合定位。 and
#Driver.find_element(By.XPATH, "//input[@class='s_ipt' and @name='wd' ]").send_keys("新闻")
# 3. 通过子元素,找父元素。 ..
#Driver.find_element(By.XPATH, "/html/body/div[@id='wrapper']/div[@id='head']/div[@id='s-top-left']/../div[@id='s-top-left']/a[1]").click()
# 4. 根据文本内容定位。
# //span[text()=' ']
# //a[text()='新闻']
#Driver.find_element(By.XPATH, "//span[text()='杭州亚运会:文化交流韵味十足']").click()
# 5. 模糊文本内容匹配。 //contains(text(),' ')
#Driver.find_element(By.XPATH, "//a[contains(text(),'新闻')]").click()
# 6. 同级弟弟元素 following-sibling::同级标签
Driver.find_element(By.XPATH, "//div[@id='s-top-left']/a[1]").click()
Driver.find_element(By.XPATH, "//div[@id='s-top-left']/a[1]/following-sibling::a[2]").click() # 从新闻,到了地图
# 7. 同级哥哥元素 preceding-sibling::同级标签
#Driver.find_element(By.XPATH, "//div[@id='s-top-left']/a[2]").click()
#Driver.find_element(By.XPATH, "//div[@id='s-top-left']/a[2]/preceding-sibling::a[1]").click() # 从hao123,到地图
time.sleep(2)
# close
Driver.quit()
九、等待
1.隐式等待(不可以干预)
Driver.implicitly_wait(1) # 大于0的参数,表示启动隐式等待
2. 显示等待(可以自定义)
ele = WebDriverWait(fixture, 10).until(
lambda _: Driver.find_element(By.XPATH,
'/html/body/div[3]/div[2]/div/div/a[2]')
)
ele.click()
lambda :匿名函数
3. 强制等待
import time
time.sleep(2)
4. 例子
# -*- coding: utf-8 -
# selenium + pytest Fixture
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
import pytest
from selenium.webdriver.support.wait import WebDriverWait
@pytest.fixture(scope='function')
def fixture():
Driver = webdriver.Firefox()
Driver.get('https://www.baidu.com/')
print("打开浏览器")
return Driver
def test_1(fixture):
url = fixture.current_url
assert url == 'https://www.baidu.com/'
button_text = fixture.find_element(By.ID, 'su').accessible_name
assert button_text == '百度一下'
fixture.find_element(By.ID, 'kw').send_keys("新闻")
fixture.find_element(By.ID, 'su').click()
# 1. 显示等待(可以自定义)
ele = WebDriverWait(fixture, 10).until(
lambda _: fixture.find_element(By.XPATH,
'/html/body/div[3]/div[2]/div/div/a[2]')
)
ele.click()
# 2. 隐式等待(不可以干预)
fixture.implicitly_wait(1) # 大于0的参数,表示启动隐式等待
fixture.get_screenshot_as_file("button.png") # 页面截图
# 3. 强制等待,问题:不知道写多少秒
sleep(2)
fixture.quit()
十、POM封装框架(page object model)
- 类:页面
- 类属性:页面中的元素
- 类方法:页面操作
简单的登陆页面的demo
BasePage.py
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
class BasePage():
def __init__(self):
self.driver = webdriver.Firefox()
# 输入网址
def get_url(self, url):
self.driver.get(url)
# 输入文本操作
def sent_keys(self, element, text):
# 2是最长的等待时间,0.5是间隔时间调用一次
ele = self.wait(2, 0.5).until(
lambda _: self.driver.find_element(*element)
)
ele.send_keys(text)
# 点击操作
def click(self, element):
ele = self.wait(2, 0.5).until(
lambda _: self.driver.find_element(*element)
)
ele.click()
# 等待页面
def wait(self, times, part):
return WebDriverWait(self.driver, times, part)
# 关闭页面
def quit(self):
self.driver.quit()
LoginPage.py
# -*- coding: utf-8 -*-
from selenium.webdriver.common.by import By
from selenuim.Base.BasePage import BasePage
from time import sleep
class LoginPage(BasePage):
# 定义页面属性
url = "网址"
username = (By.ID, "页面用户名输入")
password = (By.ID, '页面密码输入')
Btn = (By.ID, '页面的按钮')
def do_login(self, username, password):
self.get_url(self.url)
self.driver.implicitly_wait(10)
self.sent_keys(self.username, username)
self.sent_keys(self.password, password)
sleep(2)
self.click(self.Btn)
main.py
# -*- coding: utf-8 -*-
from selenuim.page.LoginPage import LoginPage
Page = LoginPage()
Page.do_login('用户名', '密码')
Page.quit()