3 - Selenium - 元素定位
selenium模拟人对浏览器的操作,那人对如何对浏览操作呢?无非也就是点、划、拖拽、输入等操作。这些操作反映到HTML中,也无非是对节点元素的操作。selenium提供了多种对于元素的操作,简单来说,就是找到标签,操作它,但是现在有些标签的属性是动态的,所以,还是要根据实际情况来选择定位方式。
常见的元素定位方式有以下几种:
- 根据ID定位,可以说这是最常用的定位方式了,因为ID是唯一的,所以用来较为方便
drier.find_element_by_id
,如果获取到多个,返回多个中的第一个。drier.find_elements_by_id
,以列表的形式返回元素,无论元素是否唯一。
- 根据class属性定位
drier.find_element_by_class_name
,如果具有class属性的元素有多个,返回多个中的第一个。drier.find_elements_by_class_name
,以列表的形式返回元素,无论元素是否唯一。
- 根据tag name定位,直接根据标签名字定位,在某些情况下也是十分方便
drier.find_element_by_tag_name
,如果获取到多个,返回多个中的第一个。drier.find_elements_by_tag_name
,以列表的形式返回元素,无论元素是否唯一。
- 根据name属性定位,常用在对input框做做操作
drier.find_element_by_name
,如果获取到多个,返回多个中的第一个。drier.find_elements_by_name
,以列表的形式返回元素,无论元素是否唯一。
- 根据link text定位,专门用来定位超链接,只不过情况有些特殊,一个就是完全匹配超链接的内容进行定位,另一种是模糊定位,也就是超链接的内容包含指定文本即可定位到
find_element_by_link_text
,绝对定位,如果获取到多个,返回多个中的第一个drier.find_elements_by_link_text
,绝对定位,以列表的形式返回元素,无论元素是否唯一。drier.find_element_by_partial_link_text
,模糊定位,如果获取到多个,返回多个中的第一个drier.find_elements_by_partial_link_text
,模糊定位,以列表的形式返回元素,无论元素是否唯一。
- 根据xpath定位,这个也不用多少了,非常的灵活方便,只不过需要一点基础
drier.find_element_by_xpath
,如果获取到多个,返回多个中的第一个drier.find_elements_by_xpath
,以列表的形式返回元素,无论元素是否唯一。
- css selector定位,这个是官方推荐的定位方式,定位方式灵活,但是需要一点前端css基础
drier.find_element_by_css_selector
,如果获取到多个,返回多个中的第一个drier.find_elements_by_css_selector
,以列表的形式返回元素,无论元素是否唯一。
- By选择器,严格意义上来说,这不是一种定位方式,而是上面几种定位方式的一种封装形式,用起来相对顺手
个人认为,这里比较难的定位方式是xpath和css selector这两种定位方式,不过凡事经不起干,多练练就行了。
后续示例以百度搜搜主页为例,围绕着输入框和确定按钮来搞。
根据id来定位
import time from selenium import webdriver from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("https://www.baidu.com/") try: obj = driver.find_element_by_id("kw").send_keys("河北疫情") except Exception as e: print(e) finally: time.sleep(5) driver.quit()
根据class来定位
import time from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com") try: # 要是有多个符合条件的 这个是找到第一个class对应的 driver.find_element_by_class_name("s_ipt").send_keys("河北疫情") except Exception as e: print(e) finally: time.sleep(5) driver.quit()
根据tag name定位
import time from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com") obj = driver.find_element_by_class_name("bg") time.sleep(4) obj.find_element_by_tag_name('input').send_keys("你好,李焕英") time.sleep(3) driver.quit()
css selector
Css Selector是我最喜欢的元素定位方法,Selenium官网的Document里极力推荐使用CSS Selector,而不是XPath来定位元素,原因是CSS Selector比XPath Selector速度快,特别是在IE下面(IE没有自己的XPath 解析器(Parser))它比xpath更高效更准确更易编写,美中不足是根据页面文字时略有缺陷没有xpath直接。
因为前端开发人员就是用CSS Selector设置页面上每一个元素的样式,无论那个元素的位置有多复杂,他们能定位到,那我们使用CSS Selector肯定也能非常精准的定位到页面Elements。
来看常用的定位方式
""" 可以根据 1.根据id 2.根据class 3.根据tag_name 4.支持匹配符,如`^`,`$`,`*` """ # 1. 根据 id import time from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com") # 1.根据id # 可以直接通过css的id找,也可以通过input框下的id找 # driver.find_element_by_css_selector("#kw").send_keys("1月16日") # driver.find_element_by_css_selector("input#kw").send_keys("1月16日") # 2.根据class # driver.find_element_by_css_selector(".s_ipt").send_keys("1月16日") # driver.find_element_by_css_selector("input.s_ipt").send_keys("1月16日") # 3.根据tag_name # 得到第一个div的id # print(driver.find_element_by_css_selector('div').get_attribute("id")) # 4.支持匹配符,如`^`,`$`,`*` driver.find_element_by_css_selector('input[id=kw]').send_keys("疫情") time.sleep(4) driver.quit()
- E[attr]:只使用属性名,但没有确定任何属性值;
- E[attr="value"]:指定属性名,并指定了该属性的属性值;
- E[attr~="value"]:指定属性名,并且具有属性值,此属性值是一个词列表,并且以空格隔开,其中词列表中包含了一个value词,而且等号前面的“〜”不能不写;
- E[attr^="value"]:指定了属性名,并且有属性值,属性值是以value开头的;
- E[attr$="value"]:指定了属性名,并且有属性值,而且属性值是以value结束的;
- E[attr*="value"]:指定了属性名,并且有属性值,而且属值中包含了value;
- E[attr|="value"]:指定了属性名,并且属性值是value或者以“value-”开头的值(比如说zh-cn);
import time from selenium import webdriver drier = webdriver.Chrome() drier.implicitly_wait(time_to_wait=10) text = '流年中渲染了微笑 - 博客园' url = 'https://www.baidu.com' drier.get(url) try: # 匹配子元素, A>B # drier.find_element_by_css_selector('form>span>input').send_keys(text) # 匹配后代元素, A空格B # drier.find_element_by_css_selector('form span input').send_keys(text) # 匹配第一个后代元素 # print(drier.find_element_by_css_selector('form :first-child').get_attribute('name')) # 返回form表单中隐藏的第一个input标签 # print(drier.find_element_by_css_selector('form span:first-child').get_attribute('class')) # 返回form表单中第一个span标签中的第一个子元素 # 根据索引匹配元素 # print(drier.find_element_by_css_selector('form :nth-child(2)').get_attribute('name')) # 返回form表单中第=二个input标签 # 匹配兄弟标签 print(drier.find_element_by_css_selector('form :nth-child(2)+input').get_attribute('name')) # 先定位到a,根据a匹配临近的b except Exception as e: print(e) finally: time.sleep(5) drier.quit()
By选择器
By选择将上面繁琐的元素定位封装了起来,这样使用起来较为方便,只是在使用By选择器前要导入:
from selenium.webdriver.common.by import By
用法如下,非常简单
import time from selenium import webdriver from selenium.webdriver.common.by import By drier = webdriver.Chrome() drier.implicitly_wait(time_to_wait=10) text = '流年中渲染了微笑 - 博客园' url = 'https://www.baidu.com' drier.get(url) try: drier.find_element(By.ID, 'kw').send_keys(text) drier.find_element(By.CLASS_NAME, 's_btn').click() except Exception as e: print(e) finally: time.sleep(5) drier.quit()
你可以直接:
By.ID
By.CLASS_NAME
By.CSS_SELECTOR
By.TAG_NAME
By.NAME
By.PARTIAL_LINK_TEXT
By.LINK_TEXT
By.XPATH
简单吧!