任务目标
- 在获取了网页的HTML代码后我们可以使用很多方法查找元素并爬取其中的数据
- Selenium支持XPath、CSS等多种查找元素的方法,掌握这些方法可以灵活地爬取到所要的数据
- 这个项目我们学习怎么样使用Selenium的XPath、CSS 等方法查找元素数据。
Selenium 提取HTML元素函数/方法
函数/方法****功能描述
find_element_by_xpath(xpath)
find_elements_by_xpath(xpath)
通过xpath定位元素find_element_by_id(id) **无find_elements_by_id(id)**通过id定位元素find_element_by_name(value)通过name定位元素find_element_by_css_selector(css)通过css定位元素find_element_by_tag_name("tag_name_vaule")通过tag_name定位元素find_element_by_class_name("class_name")通过class_name定位元素
find_element_by_link_text("text_vaule")
find_element_by_partial_link_text()
通过link定位元素
通过部分link内容定位元素
WebElement.text
WebElement. get_attribute(attrName)
查找元素的文本
查找元素的属性
注:上面的类似:
旧版本selenium格式:find_element_by_xpath(xpath)
新版本selenium格式:find_element(By.XPATH, xpath)
1. 使用XPath查找元素
(1) 函数 find_element_by_xpath(xpath):查找 xpath 匹配的第一个元素,如果找到就返回一个 WebElement 类型的对象,如果找不到就抛出异常;
(2) 函数 find_elements_by_xpath(xpath):查找xpath匹配的所有元素组成的列表,每个元素都是一个 WebElement 对象 ,如果找不到就返回空列表;
(3) 任何一个 WebElement 对象都可以调用 find_element_by_xpath 与find_elements_by_xpath 函数。
2. 使用id查找元素
函数 driver.find_element_by_id(id) 查找id编号的第一个元素,如果查找到就返回一个 WebElement 对象,如果没有找到就抛出异常
3. 使用name查找元素
(1)函数 find_element_by_name(value):查找 name=value 匹配的第一个元素,如果找到就返回一个 WebElement 类型的对象,如果找不到就抛出异常;
(2)函数find_elements_by_name(value):查找 name=value匹配的所有元素组成的列表,每个 元素都是一个WebElement对象,如果找不到就返回空列表;
4. 使用CSS查找元素
(1)函数 find_element_by_css_selector(css):查找 css 匹配的第一个元素,如果找到就返回一个 WebElement 类型的对象,如果找不到就抛出异常;
(2)函数 find_elements_by_css_selector(css): 查找css匹配的所有元素组成的列表,每个元素都是一个 WebElement 对象,如果找不到就返回空列表;
5. 使用tag name查找元素
函数 find_elements_by_tag_name(tagName):查找 tagName 匹配的所有元素,如果找到就返回一个 WebElement 列表,如果找不到列表为空。
6. 使用class查找元素
(1)函数 find_element_by_class_name(value) 查找第一个class=value的元素,如果找到就返回该元素的 WebElement 对象,如果找不到就抛出异常。
(2)函数find_elements_by_class_name(value) 查找所有class=value元素,如果找到就返 WebElement列表,如果找不到列表为空。
7. 使用文本查找超级链接
(1)函数 find_element_by_link_text(text) 查找第一个文本值为text 的超级链接元素,如果找到就返回该元素的 WebElement 对象 ,如果找不到就抛出异常。
(2)函数find_element_by_partial_link_text(text) 查找第一个文本值包含text的超级链接元素,如果找到就返回该元素的 WebElement 对象,如果找不到就抛出异常。
(3)函数 find_elements_by_link_text(text) 查找所有文本值为text 的超级链接元素,如果找到就返WebElement列表,如果找不 到列表为空。
(4)函数 find_elements_by_partial_link_text(text) 查找所有文本值 包含text的超级链接元素,果找到就返WebElement列表,如 果找不到列表为空。
8. 查找元素的文本与属性
(1) 任何一个 WebElement 对象都可以通过text属性获取它的文本,元素的文本值是它与它 的所有子孙节点的文字的组合,如果没有就返回空字符串。
(2) 任何一个 WebElement 对象都可以通过 get_attribute(attrName) 获取名称为attrName的属性值,如果元素没有 attrName 属性就返回 None。
实例-网页源码-phone.html
<html>
<head>
<style>
.pic {
display:inline-block;
width:200px;
vertical-align:top;
margin:10px;
}
.info {
display:inline-block;
width:500px;
}
.price {
margin: 10px;
color:red;
}
h3 {
display:inline-block;
}
.pl {
color:#888;
}
</style>
</head>
<body>
<div>
<div class="pic">
<img id="image" src="/images/000001.jpg" width="200"/>
</div>
<div class="info">
<div class="title">
<h3 id="title" style="display:inline-block">荣耀 9i</h3>
</div>
<div class="mark">
<span class="pl">品牌</span>:
<span name="mark">华为</span>
</div>
<div class="date">
<span class="pl">生产日期</span>:
<span name="date">2016-12-01</span>
</div>
<div class="price">
<span class="pl">价格</span>:
<span name="price">¥1200.00</span>
</div>
<div>简介:</div>
<div class="detail">
荣耀 9i 4GB+64GB 幻夜黑
<a href="#">移动联通</a>
电信 4G 全面屏手机
<a href="#">双卡双待</a>
</div>
</div>
</div>
</body>
</html>
实例 Test公共部分如下:
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome() # 启动chromedriver
# 获取HTML文件的绝对路径
file_path = os.path.abspath('phone.html') # 注:这里的phone.html必须和python程序在同一个目录下才可以使用abspath
# print(file_path) # D:..\案例代码\5_3 Selenium查找HTML元素\phone.html
# 用get打开本地HTML文件
driver.get(f'file:///{file_path}') # 注:这里必须使用绝对路径,∴ os.path.abspath()
# 查找元素如下⬇:
查找元素如下⬇:
**# 1.查找网页元素<h3>** elem = driver.find_element(By.XPATH, "//div[@class='info']//h3") print(type(elem)) # 运行结果: # <class 'selenium.webdriver.remote.webelement.WebElement'>
**# 2. 查找网页中元素<h4>** try: elem = driver.find_element(By.XPATH, "//div[@class='info']//h4") print(type(elem)) except Exception as err: print(err) # 运行结果: # Message: no such element: Unable to locate element: # {"method":"xpath","selector":"//div[@class='info']//h4"}
**# 3. 查找网页中第一个<span>元素的文本** print(driver.find_element(By.XPATH, "//div[@class='info']//span").text) # 运行结果: # 品牌
**# 4. 查找网页中<div class='mark'>中所有<span>元素的文本** elem = driver.find_element(By.XPATH, "//div[@class='mark']") elems = elem.find_elements(By.XPATH, ".//span") for elem in elems: print(elem.text) # 运行结果: # 品牌 # 华为
**# 5. 查找网页中手机的品牌** print(driver.find_element(By.XPATH, "//div[@class='info']//span[@name='mark']").text) # 运行结果: # 华为
**# 6. 查找网页中手机图像<img>的地址** print(driver.find_element(By.XPATH, "//div[@class='pic']//img").get_attribute("src")) # 运行结果: # file:///D:/images/000001.jpg
**# 7. 查找网页中手机图像<img>的 alt 属性与 xxx 属性** elem = driver.find_element(By.XPATH, "//div[@class='pic']//img").get_attribute("alt") print(type(elem), len(elem)) elem = driver.find_element(By.XPATH, "//div[@class='pic']//img").get_attribute("xxx") print(elem) # 运行结果: # <class 'str'> 0 # None # 值得注意的是<img>默认有 alt 属性,只是这个网页中没有设置, # 因此获取的 alt 属性值是空字符串,但是<img>默认没有 xxx 属性,因此得到 None。
**# 8. 查找网页中<div class='mark'>的 HTML 文本** elem = driver.find_element(By.XPATH, "//div[@class='mark']") print("innerHTML") print(elem.get_attribute("innerHTML").strip()) print("outerHTML") print(elem.get_attribute("outerHTML").strip()) # 运行结果: # innerHTML # <span class="pl">品牌</span>: # <span name="mark">华为</span> # outerHTML # <div class="mark"> # <span class="pl">品牌</span>: # <span name="mark">华为</span> # </div>
**# 9. 查找网页中 id="title"的元素文本** print(driver.find_element(By.ID, "title").text) # 运行结果: # 荣耀 9i
**# 10. 查找网页中 id="name"的元素** try: print(driver.find_element(By.ID, "name")) except Exception as err: print(err) # 运行结果: # Message: no such element: Unable to locate element: # {"method":"css selector","selector":"[id="name"]"}
**# 11. 找网页中手机品牌** print(driver.find_element(By.NAME, "mark").text) # 运行结果: # 华为
**# 12. 查找网页 name="xxx"的元素** try: driver.find_element(By.NAME, "xxx") except Exception as err: print(err) # 运行结果: # Message: no such element: Unable to locate element: # {"method":"css selector","selector":"[name="xxx"]"}
**# 13. 查找网页中手机品牌** print(driver.find_element(By.CSS_SELECTOR, "div[class='info'] span[name='mark']").text) # 运行结果: # 华为
**# 14. 查找网页中手机图像地址** print(driver.find_element(By.CSS_SELECTOR, "div[class='pic']>img").get_attribute("src")) # 运行结果: # file:///D:/images/000001.jpg
**# 15. 查找网页中<div class='mark'>下面的所有元素** elems = driver.find_elements(By.CSS_SELECTOR, "div[class='mark'] *") for elem in elems: print(elem.text) # 运行结果: # 品牌 # 华为
**# 16. 查找网页中手机型号** print(driver.find_element(By.CSS_SELECTOR, "#title").text) # 或者: print(driver.find_element(By.CSS_SELECTOR, "[id='title']").text) # 运行结果: # 荣耀 9i
**# 17. 查找<div class='mark'>元素下面的所有<span>元素** elem = driver.find_element(By.XPATH, "//div[@class='mark']") elems = elem.find_elements(By.TAG_NAME, "span") for elem in elems: print(elem.text) # 运行结果: # 品牌 # 华为
**# 18. 查找网页中手机型号** print(driver.find_element(By.TAG_NAME, "h3").text) # 运行结果: # 荣耀 9i
**# 19. 查找网页 class="pl"的所有元素** elems = driver.find_elements(By.CLASS_NAME, "pl") # 或者: elems = driver.find_elements(By.XPATH, "//*[@class='pl']") # 或者: elems = driver.find_elements(By.CSS_SELECTOR, "*[class='pl']") for elem in elems: print(elem.text) # 运行结果: # 品牌 # 生产日期 # 价格
**# 20. 查找网页<a href="#">移动联通<a>元素** print(driver.find_element(By.XPATH, "//div[@class='detail']/a").text) print(driver.find_element(By.LINK_TEXT, "移动联通").text) print(driver.find_element(By.PARTIAL_LINK_TEXT, "移动").text) print(driver.find_element(By.PARTIAL_LINK_TEXT, "动联").text) # 运行结果: # 移动联通 # 移动联通 # 移动联通 # 移动联通 # print(driver.find_element(By.LINK_TEXT, "**移动**").text) # **找不到的,因为这个函数要求文本要完全匹配。**
下一篇文章:5.4 Selenium 实现用户登录
版权归原作者 即使再小的船也能远航 所有, 如有侵权,请联系我们删除。