from selenium import webdriver
from selenium. webdriver. common. by import By
By的导入可以通过选中by,使用alt+enter键(win)或者command+enter(mac)进行快捷导入,或者将鼠标悬浮放在报错的地方,点击出现弹框中的导入方式即可
元素定位自己
元素定位有8中,分别是:通过id、class_name、tag_name、name、css、xpath、精准/模糊匹配文本 在页面上找到元素的id值后,建议copy后粘贴,不要手动输入 元素定位规则:通过我们的定位方法能够找到页面中唯一对应的元素,如果找到多个元素,就需要考虑换一种方法
id定位
id是用过id属性来进行定位,当元素的id是动态变化的(数字/随机数)时,如果只是部分随机,可以先找规律然后在进行定位;如果是全部随机,建议使用其他方式来进行定位 代码:driver.find_element_by_id("kw")#kw为id的数值
或者:driver.find_element(By.ID,"kw")
这个方法有return返回值,找不到会抛出异常;返回值是类的实例化对象 定位的返回值赋值后,可对找到的元素进行操作,例如点击、清除,获取元素信息等等,类似与DOM操作,只是不能修改
className定位(样式名)
代码:element和elements 找到一个元素,若界面有多个,默认返回第一个 driver.find_element_by_class_name("s_ipt")
找到全部的元素,返回类型为列表,列表中的每一个值都是一个element对象 driver.find_elements_by_class_name("s_ipt")
通过by选择定位方式:driver.find_element(By.CLASS_NAME,"XXX")
CLASS_NAME定位,只能支持单个的样式支持,如果是多个样式,是不支持的 ,这个时候建议使用css选择器备注,HTML的class_name中如果存在多个样式的话,会使用空格隔开
TagName和name
name定位是通过元素的name属性来进行定位,TagName定位是通过元素的TagName属性来进行定位 这两个种方式的用法和className一模一样,代码如下:
driver. find_element_by_tag_name( "span" )
driver. find_elements_by_tag_name( "span" )
driver. find_element_by_name( "wd" )
driver. find_elements_by_name( "wd" )
driver. find_element( By. NAME, "XX" )
driver. find_element( By. TAG_NAME, "XX" )
但是TagName这种方式不会常常使用,因为肯定会定位到多个,默认选中的永远是第一个,可能并不是自己想要的那个
超链接文本精准和模糊定位
当超链接元素中含有target = "_blank"
的时候,会打开一个新的窗口
driver. find_element_by_link_text( "新闻" )
driver. find_element_by_partial_link_text( "新闻" )
driver. find_elements_by_partial_link_text( "新闻" )
driver. find_element( By. LINK_TEXT)
driver. find_element( By. PARTIAL_LINK_TEXT)
万能定位方式: CSS选择器
快捷键ctrl+F,出现的调试器可以用来验证CSS选择器或者Xpath表达式 CSS 选择器只能支持H5页面和html,不能支持app页面
标签名和id
根据标签名定位:driver.find_element(By.CSS_SELECTOR,"input")
,这种方式几乎不用,因为有很大概率会定位到多个 根据ID定位,需要在值前面加一个#:driver.find_element(By.CSS_SELECTOR,"#id")
标签名+ID定位:driver.find_element(By.CSS_SELECTOR,"标签名#id")
import time
from selenium import webdriver
from selenium. webdriver. common. by import By
driver = webdriver. Chrome( )
driver. get( "https://www.baidu.com" )
driver. maximize_window( )
driver. find_element( By. CSS_SELECTOR, "#kw" ) . send_keys( "lala" )
time. sleep( 5 )
driver. close( )
根据classname/样式定位
根据className定位:driver.find_element(By.CSS_SELECTOR,".样式名")
在CSS选择器里面写样式的时候,每个样式前面都需要加点,空格不要保留 标签名+ClassName定位:driver.find_element(By.CSS_SELECTOR,"标签名.样式名")
import time
from selenium import webdriver
from selenium. webdriver. common. by import By
driver = webdriver. Chrome( )
driver. get( "https://www.baidu.com" )
driver. maximize_window( )
driver. find_element( By. CSS_SELECTOR, ".s-top-right-text.c-font-normal.c-color-t.s-top-right-new" ) . click( )
time. sleep( 5 )
driver. close( )
根据属性值定位
单属性选择定位:driver.find_element(By.CSS_SELECTOR,"标签名[属性名='属性值']")
多属性选择定位:driver.find_element(By.CSS_SELECTOR,"标签名[属性1='属性值'][属性2='属性值']")
import time
from selenium import webdriver
from selenium. webdriver. common. by import By
driver = webdriver. Chrome( )
driver. get( "https://www.baidu.com" )
driver. maximize_window( )
driver. find_element( By. CSS_SELECTOR, "input[id='kw'][name='wd']" ) . send_keys( "aa" )
time. sleep( 5 )
driver. close( )
万能定位方式:xpath
xpath其实就是一个path路径,一个描述页面元素位置信息的路径,相当于元素坐标 xpath是基于XML文档舒张结构,是XML的路径语言,用来查询文档中的节点,既可以用于XML,也可以用于HTML xpath匹配单个:driver.find_element_by_xpath("xpath表达式")
xpath匹配多有满足元素的内容:driver.find_elements_by_xpath("xpath表达式")
xpath两种定位方式: 绝对定位,类似于:“/html/body/div[1]/div[1]/div[3]/a[1]”,这种方式太不稳定,维护比较困难,经常要改并且太啰嗦,不建议使用。这个是从最顶层开始,一层一层的定位到想要定位的目标,每一层都要有 相对定位,类似于:“//*[@id=“kw”]”,比较灵活,不会经常,修改起来也容易
相对定位的规则
以//开头 只遵循一个原则:在这个html中,有没有符合表达式的元素,这个表达式不依赖于顺序,也不依赖于关系 如何在页面中验证定位表达式是否正确?F12后,将鼠标放在页面的html代码对的元素上,使用快捷键ctrl+F ,在文本框中输入表达式,如果匹配上的话,html中的代码会变为黄色,如图 //后面,首先接的是标签名(div,a,p,span等等),如果不考虑标签,则可以使用*,代表全匹配
属性匹配
标签名后面是属性,那么表达方式是://[@属性名称=“属性值”] 多个属性定位 ,使用逻辑表达式辅助,常用and后者or ,例如://a[@name="tj_briicon"and@class="s-bri c-font-normal c-color-t"]
文本内容匹配
文本内容全值匹配 ,表达式为text() ,全值匹配,精确查找。例如://span[text()="百度一下"]
如果HTML中元素的文本内容会经常变动的话,就不要使用文本内容,例如进度条,百分比等等,就不可以
属性包含
属性包含匹配 ,contains(@属性/text(),value) ,例如://span[contains(@class,"s-top-right-text ")]
;//span[contains(text(),"商丘")]
写被包含部分的时候,这部分内容必须是原始值的连续的一串才可以,不能间隔开来
层级定位
如果html中存在两个一模一样的元素,这个时候就要考虑层级定位 ,即通过他们不通过的父级或者父级的父级来进行定位例如://div [@id="u1"]//a[@name="tj_login" ]
,其中//div [@id=“u1”]为父级节点的定位,后面可以接单斜杠后者双斜杠都可以,但是建议使用双斜杠
轴定位
使用到轴定位的场景:如果元素之间有父关系,或者兄弟关系,就需要用到轴定位 轴名称有: ancestor :祖先节点,包括父节点parent :找寻父节点preceding 当前元素节点标签之前的所有节点(html页面的先后顺序)preceding-sibiling :当前元素节点标签之前的所有兄弟节点following :当前元素节点标签之后的所有节点(html页面的先后顺序)following-sibling :当前元素节点标签之后的所有兄弟节点使用语法:/轴名称::节点名称[@属性=值] ,例如://span[text()="成都十月"]/following-sibling::span
或者//*[contains(@class,"btn")]/parent::span[@id="s_btn_wr"]
(这是百度首页百度一下按钮的定位)
代码示例:
from selenium import webdriver
from selenium. webdriver. common. by import By
driver = webdriver. Chrome( )
driver. get( "www.baidu.com" )
ele = driver. find_element_by_id( "kw" )
ele. click( )
print ( ele. tag_name)
driver. find_element( By. ID, "kw" )
driver. find_element_by_class_name( "s_ipt" )
driver. find_elements_by_class_name( "s_ipt" )
driver. find_element_by_tag_name( "span" )
driver. find_elements_by_tag_name( "span" )
driver. find_element_by_name( "wd" )
driver. find_elements_by_name( "wd" )
driver. find_element_by_link_text( "新闻" )
driver. find_element_by_partial_link_text( "新闻" )
driver. find_elements_by_partial_link_text( "新闻" )
driver. find_element( By. CSS_SELECTOR, ".s-top-right-text.c-font-normal.c-color-t.s-top-right-new" ) . click( )
driver. find_element_by_xpath( '//*[@id="kw"]' )
driver. find_elements_by_xpath( '//*[@id="kw"]' )