XPATH

在拿到页面源代码之后,用 etree.HTML()etree.XML() 进行解析,或者用 etree.parse()文件进行解析。前两个接受 str 类型参数,代表页面源代码,最后一个接受 str 类型参数,代表文件路径。以上三个方法均返回 ElementTree 对象。

对于 ElementTree 对象,可以使用 xpath() 方法进行解析。该方法接受 str 类型参数,代表 xpath 的路径信息,返回的同样是 ElementTree 对象。

xpath 路径规则如下:

  1. / 表示父子关系。"/book/name" 表示标签 book 下的子标签 name
  2. // 表示任意的路径。/book/author//nick 表示标签 author 下的所有 nick 节点。返回的是一个列表。
  3. text() 来获取标签内的文本信息(这和 bs4 中的 Tag 类型中的 text 数据有本质区别,后者返回的是该标签下的————包括后代子孙标签中的所有————文本内容),并且其在路径中的形式如同父子关系一般,例如: /book/name/text()。以列表形式返回数据,所以注意,如果有多个符合条件的标签,都会被放到列表中。
  4. * 用来表示任意节点。/book/author/*/nick 就表示 author 标签的任意子标签的 nick 子标签。
  5. 如果一个标签下有多个相同名称的标签,可以通过序号来区别,出现越早的序号越小,从 1 开始而非从 0 开始。或者可以用属性来区别,语法如例:/html/body/ul/li[1]/a/text()/html/body/ol/li/a[@href='dapao']
  6. . 用于非开头位置的 ElementTree 类型,表示当前的节点。例如,我们已经找到了某个 li 标签,li.xpath("./a/text()") 表示找该 li 标签的子 a 标签里的文本内容。
  7. 如果要获取属性值,则语法为:./a/@href,同样是作为父子关系出现,@ 表示属性。

实例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from lxml import etree

xml = """
<book>
<name>hh</name>
<author>
<nick id="1">41</nick>
<nick id="2">42</nick>
<div>
<nick id="3">43</nick>
</div>
<span>
<nick id="3">44</nick>
</span>
</author>
</book>
"""

tree = etree.XML(xml);

# result = tree.xpath("/book"); # /表示层级关系,第一个是根节点。
# result = tree.xpath("/book/name")
# result = tree.xpath("/book/name/text()") # text() 是拿取文本
# result = tree.xpath("/book/author//nick/text()");
# 两个 // 表示后代,查找后代所有的 nick 节点。
result = tree.xpath("/book/author/*/nick/text()");
# * 表示任意的节点,通配符。

print(result);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from lxml import etree
tree = etree.parse("b.html");
# result = tree.xpath("/html/body/ul/li/a/text()");
# result = tree.xpath("/html/body/ul/li[1]/a/text()"); # xpath 的顺序是从 1 开始数的。
# result = tree.xpath("/html/body/ol/li/a[@href='dapao']/text()"); # [@xxx=xxx]

ol_li_list = tree.xpath("html/body/ol/li");

# print(result);

for li in ol_li_list:
result = li.xpath("./a/text()");
# ./ 表示相对查找,.表示当前节点。
result2 = li.xpath("./a/@href")

print(tree.xpath("/html/body/ul/li/a/@href"));

# 可以在浏览器检查页面(F12)中对于网页源代码直接右键节点可以复制 xpath。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests
from lxml import etree

url = "https://www.zbj.com/fw/?k=saas";
resp = requests.get(url);
# print(resp.text);

# with open("zbj.html", "w", encoding="utf-8") as f:
# f.write(resp.text);

html = etree.HTML(resp.text);
etree

# 拿到每一个服务商。
divs = html.xpath('//*[@id="__layout"]/div/div[3]/div[1]/div[4]/div/div[2]/div/div[2]/div')

for div in divs:
price = div.xpath("./div/div/div[@class='price']/span/text()");
print(price);
# break;

resp.close();