Selenium+Python定位详解(完整版)

基础介绍

通过Chrome浏览器自带的开发者工具可以看到,页面元素都是由HTML语言组成的,它们之间有层级地组织起来,每个元素有不同的标签名和属性值,Selenium中WebDriver就是根据这些信息来定位的。

WebDriver提供了8种元素定位方法,在Python中,对应的方法如下:

name Python
id定位 find_element_by_id()
name定位 find_element_by_name()
tag定位 find_element_by_tag_name()
class定位 find_element_by_class_name()
link_text定位 find_element_by_link_text()
partial link定位 find_element_by_partial_link_text()
Xpath定位 find_element_by_xpath()
CSS_selector定位 find_element_by_css_selector()

下面详细介绍如何使用这些定位方法,首先复制百度首页的部分前端代码,用于举例说明:

<!-- 该部分为百度首页搜索框与搜索按钮的部分HTML示意(不排除有后续调整id等标签信息的可能性,仅以当时举例) -->
<span id="s_kw_wrap" class="bg s_ipt_wr quickdelete-wrap">
<span class="soutu-btn"></span>
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
<a href="javascript:;" id="quickdelete" title="清空" class="quickdelete" style="top: 0px; right: 0px; display: none;"></a>
</span>
...
<span class="btn_wr s_btn_wr bg" id="s_btn_wr">
<input type="submit" value="百度一下" id="su" class="btn self-btn bg s_btn">
</span>

id定位

HTML规定,HTML标签的id属性值必须是唯一的(如果不唯一,请麻烦前端背锅)。WebDriver提供的id定位方法是通过元素的id来查找元素的,通过id定位百度输入框与百度搜索按钮的示例如下:

driver.find_element_by_id("kw")
driver.find_element_by_id("su")

name定位

name用来指定元素的姓名(name可以重复),即HTML元素的name属性,通过标签的name属性定位百度输入框的用法如下:

driver.find_element_by_name("wd")

class定位

class用来指定元素的类名,即HTML元素的class属性,通过标签的class属性定位百度输入框的用法如下:

driver.find_element_by_class_name("s_ipt")

tag定位

tag用来定义不同页面的元素,即HTML元素的标签名,如input标签、a标签等,通过tag name定位百度输入框的用法如下:

driver.find_element_by_tag_name("input")

很少用到。


link_text定位

link_text专门用来定位文本链接,例如百度输入框上面几个文字链接的HTML如下:

<div id="u1"><a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a>
<a href="https://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a>
<a href="http://map.baidu.com" name="tj_trmap" class="mnav">地图</a>
<a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a>
<a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">贴吧</a>
<a href="http://xueshu.baidu.com" name="tj_trxueshu" class="mnav">学术</a>

以下为link_text定位链接的用法(当然是用id或者name都是个不错的选择):

driver.find_element_by_link_text("新闻")
driver.find_element_by_link_text("hao123")
driver.find_element_by_link_text("地图")
driver.find_element_by_link_text("视频")
driver.find_element_by_link_text("贴吧")
driver.find_element_by_link_text("学术")

partial link定位

partial link用于对link定位的补充,可以取文字链接的部分文字进行定位,注意,需要这部分文字可以唯一地标识这个链接。

<a class="mnav" id="u1">一个很长的文本链接</a>

通过partial link定位如下:

driver.find_element_by_partial_link_text("一个很长的")
driver.find_element_by_partial_link_text("文本链接")

Xpath定位

Xpath通过元素的路径、属性或者结合层级与属性来进行元素定位。对于要使用Xpath进行定位,而又不了解Xpath的人来说,最省事的办法无非是使用浏览器自带的开发者工具进行Xpath提取:
Xpath.png

Copy XPath与Copy full XPath的区别在于,前者会复制混合定位的Xpath,后者则是从HTML头部开始到该元素所在位置的全XPath路径。

1.绝对路径定位

driver.find_element_by_xpath("/html/body/div[2]/div[2]/div[5]/div[1]/div/form/span[1]/input")

如需了解详细XPath定位,请移步至XPath教程

2.元素属性定位

driver.find_element_by_xpath('//input[@id="kw"]')
driver.find_element_by_xpath('//*[@id="su"]')

input表示当前页面某个input标签,*号表示不指定标签名,[@id="kw"]表示这个元素的id值是kw。同理可得:

driver.find_element_by_xpath('//*[@name="wd"]')
driver.find_element_by_xpath('//*[@class="s_ipt"]')

上述XPath定位并不仅限于@id、@name、@class,只要目标定位元素的属性能唯一标识这个元素,即使用该属性进行标识。

3.混合定位

如果一个元素本身没有可以唯一标识这个元素的属性值,那么可以查找能唯一标识的父级元素,再按层级向下查找至目标元素即可,即以能唯一标识的父级元素为起点,至目标元素的路径进行定位。

driver.find_element_by_xpath('//span[@class="bg s_ipt_wr"]/input')

即通过span[@class="bg s_ipt_wr"]找到百度输入框的父级元素,/input表示父级元素下面的input子元素,若该父级元素下存在多个input标签的子元素,则可以通过/input[0]、/input[1]等用于区分是第几个元素。

4.使用逻辑运算符

如果一个属性不能唯一区分一个元素,name可以使用逻辑运算符连接多个属性来查找元素。

driver.find_element_by_xpath('//input[@id="kw" and @class="s_ipt"]')

表示某个input标签中id为kw且class为s_ipt的元素,仅以id和class属性进行举例,可替换成其他属性。使用频率较低。

5.使用contains方法

contains方法用于匹配一个属性中包含的字符串。

driver.find_element_by_xpath('//span[contains(@class,"s_ipt_wr)")]')

表示定位class名包含s_ipt_wr的span标签。使用频率较低。

6.使用text()方法

text()方法用于匹配显示文本信息,如link_text定位可改写为:

driver.find_element_by_xpath('//a[text(),"新闻")]')

即匹配标签文本为新闻的a标签。
也可以和上述contains方法结合使用:

driver.find_element_by_xpath('//a[text(),"新闻")]')

即匹配标签文本包含新闻的a标签,同partial link定位。


CSS定位

CSS是一种语言,用来描述HTML文档的样式,通过CSS定位需要了解部分CSS知识,CSS选择器的常见语法如下:

选择器 例子 描述
.class .intro class选择器,选择class="intro"的所有元素
#id #firstname id选择器,选择id="firstname"的所有元素
* * 选择所有元素
element p 选择所有<p>元素
element>element div>input 选择父元素为<div>的所有<input>元素
element+element div+input 选择同一级中紧接在<div>元素只有的所有<input>元素
[attribute=value] [target=_blank] 选择target="_blank"的所有元素

1.通过class定位

driver.find_element_by_css_selector(".s_ipt")
driver.find_element_by_css_selector(".s_btn")

定位页面中class为s_ipt、s_btn的元素,点号(.)在CSS中用于指代class名。

2.通过id定位

driver.find_element_by_css_selector("#kw")
driver.find_element_by_css_selector("#su")

定位页面中id为kw、su的元素,井号(#)在CSS中用于指代id名。

3.通过标签名定位

driver.find_element_by_css_selector("input")

定位页面中标签为input的元素,使用标签名定位元素是不需要任何符号标识,直接使用标签名即可。

4.通过标签层级关系定位

driver.find_element_by_css_selector("span > input")

定位页面中父元素为span的所有input元素。

5.通过属性定位

driver.find_element_by_css_selector("[autocomplete=off]")
driver.find_element_by_css_selector("[name='kw']")
driver.find_element_by_css_selector('[type="submit"]')

定位页面中属性autocomplete=off、name='kw'、type="submit"的元素,同前面所说的属性定位方法,只要该属性能唯一标识这个元素,均可以进行定位。

6.组合定位

driver.find_element_by_css_selector("form.fm > span > input.s_ipt")
driver.find_element_by_css_selector("form#form > span > input#kw")

定位页面中标签名为input,class属性为s_ipt,父元素为span,父元素的父元素为form且class属性为fm的元素。

7.更多定位用法

CSS选择器的更多用法可以查看CSS选择器参考手册


用By定位元素

用By定位元素和前面所述的八种基本定位方法相同,仅仅是写法上略有不同而已,具体如下:

name Python By定位元素
id定位 find_element_by_id() find_element(By.ID, "kw")
name定位 find_element_by_name() find_element(By.NAME, "wd")
tag定位 find_element_by_tag_name() find_element(By.CLASS_NAME, "s_ipt")
class定位 find_element_by_class_name() find_element(By.TAG_NAME, "input")
link_text定位 find_element_by_link_text() find_element(By.LINK_TEXT, "新闻")
partial link定位 find_element_by_partial_link_text() find_element(By.PARTIAL_LINK_TEXT, "新")
Xpath定位 find_element_by_xpath() find_element(By.XPATH, "//*[@id='su']")
CSS_selector定位 find_element_by_css_selector() find_element(By.CSS_SELECTOR, "span.bh s_btn_wr>input#su")

以上就是全部Selenium+Python定位的介绍了。

欢迎访问我的个人博客:Lemon - 万事顺遂

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容