XPath(XML Path Language - XML路径语言),它是一种用来确定XML文档中某部分位置的语言。
Xpath以XML为基础,提供用户在数据结构树中寻找节点的能力,Xpath被很多开发者亲切的称为小型查询语言
xpath使用路径表达式在xml和html中进行导航,适用于xml和html所以在爬虫中作为解析库使用
xpath包含标准函数库
xpath是w3c的标准,脱离语言
xpath节点关系
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从当前节点选取直接子节点 |
// | 从当前节点选取子孙节点 |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
示例:
表达式 | 描述 |
---|---|
//article[@lang=‘cn’] | 选取所有名称为article,同时属性lang值为cn的节点,[]谓语 |
article | 选取所有article元素的所有子节点 |
/article | 选取根元素article |
article/a | 选取所有属于article的子元素的a元素 |
//div | 选取所有div子孙元素(不论出现在文档任何地方) |
article//div | 选取所有属于article元素的后代的div元素,不管它出现在article之下的任何位置 |
//@class | 选取所有名为class的属性 |
/article/div[1] | 选取属于article子元素的第一个div元素 |
/article/div[last()] | 选取属于article子元素的最后一个div元素 |
/article/div[last()-1] | 选取属于article子元素的倒数第二个div元素 |
//div[@lang] | 选取所有拥有lang属性的div元素 |
//div[@lang=‘eng’] | 选取所有lang属性为eng的div元素 |
/div/* | 选取属于div元素的所有子节点 |
//* | 选取所有元素 |
//div[@*] | 选取所有带属性的div元素 |
//div/a | //div/p | 选取所有div元素的a和p元素 |
//span | //ul | 选取文档中的span和ul元素 |
article/div/p| //span | 选取所有属于article元素的div元素的p元素 以及文档中所有的span元素 |
html基本结构
<html>
<head>
<title></title>
</head>
<body>
<div id="1"></div>
<div id="2">
<div id="3"></div>
<div id="4"></div>
</div>
</body>
</html>
对于节点关系
兄弟节点:
div1和div2互为兄弟节点
父节点和子节点
div3和div4的父节点是div2,他们是div2的子节点,每个节点都有唯一的父节点
祖先节点和子孙节点
div都是body的子孙节点,body是div的祖先节点
一般静态页面的解析都是定位a标签获取href
选取多个属性可以用 and or |
div[@class="info_list password" and @node-type="password_box"]
div[@class="info_list password" or @node-type="password_box"]
div[@class="info_list password" | @node-type="password_box"]
函数
获取元素的文本
//*[@id="entry_737487"]/div[2]/h2/a/text()
获取最后一个元素
a[last()]
直接使用 @
获取所有li节点下a节点的href属性
//li/a/@href
# 获取所有a标签(text包含 Next >的)的href属性
//a[contains(text(), 'Next >')]/@href
# 获取所有a标签(class属性包含 Next >的)
//a[contains(@class, 'Next >')]
在F12浏览器调试中可以Ctrl+Shift+C,或直接选择器选中元素右键copy,选择xpath复制
def parse(self, response):
# 不建议的写法
# /html/body/div[2]/div[2]/div[4]/div[1]/div[2]/h2/a/@href
# 路径短
# //*[@id="entry_732084"]/div[2]/h2/a/@href 该方法写死了id
href = response.xpath('//*[@id="entry_732084"]/div[2]/h2/a/@href')
# 提出字符串值,返回list,["",""]
val_list = href.extract()
# 提出字符串值,返回第一个结果
val_first = href.extract_first(default="")
print(val_first)
# 推荐写法
href = response.xpath('//div[@id="news_list"]/div[1]/div[2]/h2/a/@href')
print(href.extract_first(default=""))
# 推荐写法,缩短路径
href = response.xpath('//div[@id="news_list"]//h2/a/@href')
print(href.extract_first(default=""))
# 推荐写法,缩短路径,指定父节点
href = response.xpath('//div[@id="news_list"]//h2[@class="news_entry"]/a/@href')
print(href.extract_first(default=""))
pass
# //* 忽略前面的节点 [@id="xx"] 通过id定位到节点减少路径
Selector使用xpath
from scrapy.selector import Selector
Selector(text=browser.page_source).xpath(
'//*[@id="boardfeed:287808301125883930"]/div/div[1]/div[1]/div/div/div/div/div[1]/a/div/div/div/div/div[1]/img').extract()
lxml
from lxml import etree
index_url = "https://www.baidu.com"
index_resp = requests.get(index_url, headers=headers)
index_tree = etree.HTML(index_resp.text)
suf_list = index_tree.xpath(
'//div[@class="title"]/a/@href')