|
XPath解析
XPath(XML Path Language)是一种用于在XML和HTML文档中查找信息的语言,其通过路径表达式来定位节点,属性和文本内容,并支持复杂查询条件,XPath 是许多 Web 抓取工具如 Scrapy,Selenium 等的核心技术之一
XPath 解析的基本步骤
- 导入lxml.etree
- 使用etree.parse(filename, parser=None)函数返回一个树形结构
- etree.parse()用于解析本地XML或HTML文件,并将其转换为一个树形结构即ElementTree对象,可以通过该对象访问文档的各个节点
- filename:要解析的文件路径
- parser(可选):默认情况下,parser()会根据文件扩展名自动选择合适的解析器,如.xml文件使用XML解析器,.html使用HTML解析器
- 使用etree.HTML(html_string, parser=None)解析网络html字符串
- html_string :要解析的HTML字符串
- parser:(可选):默认情况下etree.HTML()使用etree.HTMLparser()进行解析
- 返回值:etree.HTML()返回一个ELement对象,表示HTML文档的根元素,可以通过该对象访问文档各个节点
- 使用.xpath(xpath_expression)在已经解析好的HTML文档中执行XPath查询
- result = html_tree.xpath(xpath_expression)
复制代码
- xpath_expression:XPath表达式,用于在文档中查找节点,XPath表达式可以是绝对路径或相对路径,也可以包含谓词,函数和轴操作,主要的XPath语法下面会展开讲解
- html_tree:可以是 ElementTree 对象(由 etree.parse() 返回)或 Element 对象(由 etree.HTML() 返回)
- from lxml import etree
- # 使用etree.parser()解析文件路径
- parser = etree.HTMLParser(encoding='utf-8') # 以utf8进行编码
- tree = etree.parse('../Learning02/三国演义.html', parser=parser)
- print(tree)
- #output-> <lxml.etree._ElementTree object at 0x000001A240107000>
- # 使用etree.HTML()解析本地文件或网络动态HTML
- # 读取文件 解析为字符串
- file = open('../Learning02/三国演义.html', 'r', encoding='utf-8')
- data = file.read()
- root = etree.HTML(data)
- print(root)
- #整合
- root = etree.HTML(open('../Learning02/三国演义.html', 'r', encoding='utf-8').read())
- print(root)
- #output-> <Element html at 0x1a23e462880>
复制代码 XPath语法
XPath语法可以用于在XML与HTML文档中查找信息的语言
路径表达式
XPath使用路径表达式来定位文档中的节点,路径也可以分为绝对路径与相对路径
绝对路径
从根节点html开始查找到head,再从head下找出title标签- root = etree.HTML(open('../Learning02/三国演义.html', 'r', encoding='utf-8').read())
- all_titles = root.xpath('/html/head/title')
- for title in all_titles:
- print(etree.tostring(title, encoding='utf-8').decode('utf-8'))
- #output-> <title>《三国演义》全集在线阅读_史书典籍_诗词名句网</title>
复制代码 相对路径
相比与绝对路径,相对路径使用率更好,更好用
- //:表示从当前节点开始,选择文档中所有符合条件的节点,并且不考虑他们的位置
- root = etree.HTML(open('../Learning02/三国演义.html', 'r', encoding='utf-8').read())
- all_a = root.xpath('//a')
- for a in all_a:
- print(a.text)
- #None
- #首页
- #分类
- #作者
- #...
复制代码 当前节点
- ./:表示当前节点,通常用于指明当前节点本身,避免混淆
- all_a = root.xpath('//a')
- print(all_a[1].xpath('./text()')) #./表示当前的a标签
- #output-> ['首页']
复制代码 选择属性
- # 使用 @ 选择 <a> 标签的 href 属性
- all_hrefs = root.xpath('//a[@href]')
- for hrefs in all_hrefs:
- print(etree.tostring(hrefs, encoding='unicode'))
复制代码 XPath谓语
谓语是xpath中用于进一步筛选节点的表达式,通常放在方括号[] 内,其可以基于节点的位置,属性值,文本内容或其他条件来选择特定的节点,谓语可以嵌套使用,也可以与其他谓语组合使用
- 基本语法
- element:要选择的元素
- condition:谓语中的条件,用于进一步筛选符合条件的元素
位置谓语
位置谓语用于根据节点在兄弟节点中的位置进行选择,可以使用position()或直接指定位置编号
<ul>获取第一个ul标签中的第一个li标签- #//ul获取的是所有ul,[0]选择第一个
- lis = root.xpath('//ul')[0].xpath('./li[1]')
- for li in lis:
- print(etree.tostring(li, encoding='unicode'))
- #output-> <li><a target="_blank" href="https://www.cnblogs.com/">首页</a></li>
复制代码 使用last()获取最后第一个节点,和导数第二个节点- # 倒一个
- last_li = root.xpath('//ul')[0].xpath('./li[last()]')
- print(etree.tostring(last_li[0], encoding='unicode'))
- # 倒二个
- last_second_li = root.xpath('//ul')[0].xpath('./li[last()-1]')
- print(etree.tostring(last_second_li[0], encoding='unicode'))
- #output-> <li><a target="_blank" href="https://www.cnblogs.com/app/">安卓下载</a></li>
- #<li><a target="_blank" href="https://www.cnblogs.com/book/">古籍</a></li>
复制代码 使用position()获取位置进行筛选
[code]# 获取前两个li标签last_li = root.xpath('//ul')[0].xpath('./li[position() |
|