爬虫解析库:lxml 与 xpath 使用小记

​ 通过 requests 模块,我们可以很简单地把网页下载到本地,但是此时获取的网页都是未经处理的,冗余的信息太多,无法进行分析和利用。那么怎么从网页中筛选自己需要的信息呢?

​ 说到信息筛选我们可能会想到正则表达式,不过由于正则表达式过于复杂而且容错率低,网页有稍微的改动就要重写匹配表达式,对于新手来说十分不友好。

​ 那么我们应该使用什么呢?别担心,我们还有很多种解析 HTML页面的方法,例如:Xpath

lxml

lxml 是一款高性能的 Python XML 解析库,它天生支持 XPath1.0,XSLT1.0,定制元素类,甚至 Python风格的数据绑定接口。它构建在两个 C 库之上:libxml2libxslt。它们为执行解析,序列化和转换等核心任务提供了主要动力

安装

pip install lxml

使用

lxml 中大部分的功能都位于 lxml.etree 模块中,导入 lxml.etree 模块的常见方式如下:

from lxml import etree
  • etree.HTML(string)

    将 string 解析为 Element 或者 ElementTree,同时修复非法标签

  • etree.parse(<file_name>)

    将文件或者是 file_like 对象解析为 ElementTree (not an Element object)

  • etree.tostring(Element, encoding=‘utf-8’)

    将一个 Element 或者 ElementTree 转换为 string 形式

  • ElementTree.write(file)

    这个是 ElementTree 特有的方法,将 ElementTree 写到 file 中

Element 属性描述
.tag元素名称
.attrib元素属性的字典
.text第一个子元素标签之前的文本。Element的文本均为直接自文本,不包含子元素中的文本
.tailElement 的关闭标签之后的文本,并且是在下一个标签之前的部分,没有则为None
Element 方法描述
append(child)添加一个子节点到当前 Element
insert(index,element)插入子元素 element 到指定位置
clear()移除 element 所有内容
remove(child)将子节点从 Element 中移除
getchildren()返回 Element 子元素的列表
iterchildren(tag=etree.Element, reversed=False)通过设置 reversed 可以反向顺序迭代子元素
getiterator(tag=None,*tags)递归返回 Element 子元素的生成器,可使用 tag 参数过滤返回的元素,深度优先,先根遍历
getroottree()返回元素的 Elementree
iter(tag=None,*tags)过滤特定标签,生成迭代器。默认情况下,iter() 迭代所有的节点,包括PI(处理指令) 、Comment(注释) 等。如果只想迭代标签元素,可以使用 Element factory 做参数 e.iter(tag = etree.Element)
itertext(tag=None, *tags, with_tail=True)迭代 Element 元素的文本内容,with_tail 参数决定是否迭代子元素的 tail 。Element 的tail 不会进行迭代
iterancestors( tag=None )迭代所有 Element 先辈,可以使用 tag 过滤
itersiblings( preceding=False )迭代 Element 之后的兄弟元素,可以通过设置 preceding=True 仅迭代 Element 之前的兄弟元素
items()返回 Element 属性的键值所构成的(name,value)元组的列表
keys()返回元素属性名的列表
get(key,default=None)返回字符串形式的 属性 key 的值,没有返回 None
set(A,V)创建或者改变属性 A 的值为 V

什么是Xpath

Xpath,全称 XML Path Language,即 XML路径语言,是一门在 XML文档中查找信息的语言,最初用来搜寻 XML文档,但是它同样适用于 HTML文档的搜索

Xpath中,有七种类型的节点:元素,属性,文本,命名空间,处理指令,注释以及文档节点(根节点)

Xpath 使用路径表达式选取节点。节点是通过沿着路径或者 step 来选取的

节点关系

<bookstore>

<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

</bookstore>
节点关系描述
父(Parent)book元素是 titleauthor 等元素的父
子(Children)titleauthorbook 元素的子
同胞(Sibling)拥有相同的父节点,titleauthoryear都是同胞
先辈(Ancestor)某节点的父,父的父等。title 元素的先辈是 bookbookstore
后代(Descendant)某节点的子,子的子等。bookstore 的后代是 booktitle

常用规则

选取节点,常用路径表达式
表达式描述
/从根节点选取
//选取所有节点,不考虑它们的位置
.选取当前节点
选取当前节点的父节点
@选取属性
nodename选取此节点的所有子节点
*匹配任何元素节点
@*匹配任何属性节点
text()取标签当中的值
谓语

谓语的作用就是做过滤的,过滤条件写在 []

表达式描述
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素
/bookstore/book[last()]选取属于 bookstore 子元素的倒数第二个 book 元素
/bookstore/book[position()< 3]选取最前面的两个属于 bookstore 元素的子元素的 book 元素
//book[@lang]选取所有拥有名为 lang 的属性的 title 元素
//book[@lang=‘eng’]选取所有拥有 lang 属性值为 eng 的 book 元素
//book[price>35]选取所有拥有 price元素且值大于35 的 book 元素
运算符
运算符描述
|返回两个节点集
+加法。6+4=10
-减法。6-4=2
*乘法。3*2=6
div除法。4 div 2 = 2
mod余数。5 mod 2 = 1
=等于。1=1 返回 true
!=不等于。9 != 9 返回 false
<小于
<=小等于
>大于
>=大等于
or
and

通过 轴 可以获取 祖先节点,属性值,兄弟节点等

使用方式:轴::[谓语]

  • child::* :所有子节点
  • child::div :所有 div 子节点
  • child::div[@class='item']:所有 class=item 的 div 子节点
描述
ancestor选取当前节点的所有先辈(父、祖父等)。
ancestor-or-self选取当前节点的所有先辈(父、祖父等)以及当前节点本身。
attribute选取当前节点的所有属性。
child选取当前节点的所有子元素。
descendant选取当前节点的所有后代元素(子、孙等)。
descendant-or-self选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
following选取文档中当前节点的结束标签之后的所有节点。
following-sibling选取当前节点之后的所有兄弟节点
preceding选取文档中当前节点的开始标签之前的所有节点。
preceding-sibling选取当前节点之前的所有同级节点。
namespace选取当前节点的所有命名空间节点。
parent选取当前节点的父节点。
self选取当前节点。
函数
函数描述
position()返回节点的 index 的位置
last()返回节点的个数
contains(string1, string2)string1 是否包含 string2
text()返回文本节点
comment()返回注释节点
normalize-space(string)去除首位空格,中间多个空格用一个空格代替
substring(string, start, len)返回从 start 位置开始的指定长度的子字符串,第一个字符下标为1
substring-before(string1, string2)返回 string1中位于第一个 string2 之前的部分
substring-after(string1, string2)返回string1中位于第一个string2之后的部分

使用示例

# 获取父节点             获取 id=title 的 a 标签 父元素的 class 属性
xpath('//a[id="title"]/../@class')

# 模糊查询              获取 class 以 it 开头的 a 标签
xpath('//a[contains(@class, "it")]')

# 多条件匹配
xpath('//a[@class="title" and @name="t"]')

# 指定位置匹配
# ul 中最后一个 li 标签
xpath('//ul/li[last()]')

# ul 中倒数第二个 li 标签
xpath('//ul/li[last()-1]')

# ul 中前三个 li 标签
xpath('ul/li[position<4]')
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值