[转载]Python爬虫之xpath使用技巧
原文地址: 知乎-Python爬虫之xpath使用技巧
XPath是一种表达式语言,它的返回值可能是节点,节点集合,原子值,以及节点和原子值的混合等。XPath2.0是XPath1.0的超集。它是对XPath1.0的扩展,它可以支持更加丰富的数据类型,并且XPath2.0保持了对XPath1.0的相对很好的向后兼容性,几乎所有的XPath2.0的返回结果都可以和XPath1.0保持一样。另外XPath2.0也是XSLT2.0和XQuery1.0的用于查询定位节点的主表达式语言。XQuery1.0是对XPath2.0的扩展。
模块安装
pip install lxml -i https://pypi.doubanio.com/simple/
测试文件
test.html
<!DOCTYPE html> <html> <head> <title>xpath测试文件</title> </head> <body> <div> <ul> <li class="item-1 active first"><a href="link1.html">first item</a></li> <li class="item-2 li"><a href="link2.html">second item</a></li> <li class="item-3 li"><a href="link3.html">third item</a></li> <li class="item-4"><a href="link4.html">fourth item</a></li> <li class="item-5 last"><a href="link5.html">fifth item</a></li> </ul> </div> <div price="99.8"> <div> <ul> <li>时间</li> <li>地点</li> <li>任务</li> </ul> </div> <div id='testid' data-h="first"> <h2>这里是个小标题</h2> <ol> <li data="one">1</li> <li data="two">2</li> <li data="three">3</li> </ol> <ul> <li code="84">84</li> <li code="104">104</li> <li code="223">223</li> </ul> </div> <div> <h3>这里是H3的内容 <a href="http://www.baidu.com">百度一下</a> <ul> <li>test1</li> <li>test2</li> </ul> </h3> </div> <div id="go"> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> </div> </div> </body> </html>
基础语法
导入lxml库
from lxml import etree
读取html文件
html = etree.parse('test.html')
获取html内容
html_data = etree.tostring(html, pretty_print=True) res = html_data.decode('utf-8') print(res)
输出结果
获取所有a标签href属性
hrefs = html.xpath('//a/@href') print(hrefs) >> ['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html', 'http://www.baidu.com']
查找a标签href属性等于link1.html的内容
a_href_link1_text = html.xpath('//a[@href="link1.html"]/text()') print(a_href_link1_text) >> ['first item']
查找所有li标签下的a标签内容
li_children_a_text = html.xpath('//li/a/text()') print(li_children_a_text) >> ['first item', 'second item', 'third item', 'fourth item', 'fifth item']
查找第一个li标签里的a标签的href属性值
li_first_a_href = html.xpath('//li[1]/a/@href') print(li_first_a_href) >> ['link1.html']
查找最后一个li标签里的a标签的href属性值
li_last_a_href = html.xpath('//li[last()]/a/@href') print(li_last_a_href) >> ['link5.html']
查找倒数第二个li标签里的a标签的href属性值
li_secondLast_a_href = html.xpath('//li[last()-1]/a/@href') print(li_secondLast_a_href) >> ['link4.html']
高级语法
查找class属性中包含active关键字的标签下的a标签的href属性值
contains_active_a_href = html.xpath('//*[contains(@class, "active")]/a/@href') print(contains_active_a_href) >> ['link1.html']
查找class属性中开始位置包含item-4关键字的标签下的a标签的href属性值
start_item4_a_href = html.xpath('//*[starts-with(@class,"item-5")]/a/@href') print(start_item4_a_href) >> ['link5.html']
查找class属性中含有item-2和li等关键词的内容
contains_item2AndLi_text = html.xpath('//*[contains(@class,"item-2") and contains(@class,"li")]//text()') print(contains_item2AndLi_text) >> ['second item']
匹配包含code属性的所有属性值
code_values = html.xpath('//@code') print(code_values) >> ['84', '104', '223']
多条件匹配
terms_text = html.xpath('//div[@id="testid"]/h2/text() | //li[@data]/text()') print(terms_text) >> ['这里是个小标题', '1', '2', '3']
选取div标签id属性为testid下的所有子节点ul标签下的li标签的内容
div_childrens_ul_li_text = html.xpath('//div[@id="testid"]/child::ul/li/text()') print(div_childrens_ul_li_text) >> ['84', '104', '223']
选取div标签中的所有属性值
div_attributes = html.xpath('//div/attribute::*') print(div_attributes) >> ['99.8', 'testid', 'first', 'go']
定位div标签id属性为testid的父元素的price属性
div_ancestor_price = html.xpath('//div[@id="testid"]/ancestor::div/@price') print(div_ancestor_price) >> ['99.8']
定位div标签id属性为testid的节点和父元素的节点的所有属性值
div_ancestorOrSelf_attributes = html.xpath('//div[@id="testid"]/ancestor-or-self::div/attribute::*') print(div_ancestorOrSelf_attributes) >> ['99.8', 'testid', 'first']
定位div标签id属性为testid之后不包含id属性的div标签下所有的li中第一个li的text属性
div_notID_li1_text = html.xpath('//div[@id="testid"]/following::div[not(@id)]/.//li[1]/text()') print(div_notID_li1_text) >> ['test1']
选取div标签id属性为testid节点下的所有命名空间节点
div_namespaces = html.xpath('//div[@id="testid"]/namespace::*') print(div_namespaces) >> [('xml', 'http://www.w3.org/XML/1998/namespace')]
选取data值为one的父节点的子节点中最后一个节点的值 ps:注意这里的用法,parent::父节点的名字
parent_dataOne_ol_li1_text = html.xpath('//li[@data="one"]/parent::ol/li[last()]/text()') print(parent_dataOne_ol_li1_text) >> ['3']
选取div标签id属性为testid节点标签开始之前的div标签下的ul标签第一个li标签的内容
div_preceding_div_ul_li1_text = html.xpath('//div[@id="testid"]/preceding::div/ul/li[1]/text()') print(div_preceding_div_ul_li1_text) >> ['时间']
统计li标签属性为data的数量
li_data_count = html.xpath('count(//li[@data])') print(li_data_count) >> 3.0
>> 第六篇|非结构化与结构化数据提取之Xpath
关注公众号【时光python之旅】,在这里你能学到更多Python知识。