Xpath是XML路径语言,通过这个语言,我们可以在XML于HTML中查找我们想要的信息。

Xpath扩展工具及使用

  1. 在浏览器中安装相关的Xpath扩展工具,Chrome中安装Xpath Helper。(无法科学上网可以通过Here 下载。)
  2. 打开开发人员工具(F12),右键复制Xpath路径
    image-20211223095505555
  3. Shift + Ctrl + X 打开Xpath Helper,将复制内容输入进去
    image-20211223100359531

Xpath语法

路径表达式语法

表达式 路径表达式及描述
节点名称 bookstore,选取 bookstore 下的所有子节点(标签)
/ /bookstore,从根节点下选取所有 bookstore 节点(子元素)
// //bookstore,从全局节点中选择 bookstore 节点
@ //div[@price=‘a’],选择所有 price 属性为 a 的 div
. ./input,选择当前节点下的 input

谓语

表达式 描述
//ul/li[1] 选择 ul 下的第一个 li
//ul/li[last()-0] 选择 ul 下的最后一个 li
//ul/li[last()-1] 选择 ul 下的倒数第二个 li
//ul/li[position()<4] 选择 ul 下前面的 3 个子元素
//ul/li[position()>1] 选择第二个到最后的所有子元素
//li[position()>1] [position()<11] 在(2,+∞)中选择前十个
text() 获取函数文本
@class 获取标签的class

通配符

* /bookstore/*,通配符,匹配 bookstore 下的所有子元素
@* //div[@*],选择所有带有属性的 div

运算符

  • "|" —> //title | //ul[@class=‘item_con_list’],选择 title 和对应的 ul

使用xlml解析html

python实现Xpath解析需要第三方库lxml的支持

pip install lxml

Demo

爬取本站'笔记'下的所有文章标题及特色图片

from lxml import etree
from lxml.html import fromstring, tostring

import requests
# 开始爬取
resp = requests.get(
    url="https://blog.ikedong.cn/notes/",headers={'User-Agent':'BaiduSpider'}
)
# 将字符串解析位HTML文档
tree = etree.HTML(resp.text) 
# 爬取标题
title = tree.xpath('//*[@id="main"]/article[*]/div/h1/a')
# 爬取标题图片
image = tree.xpath('//*[@id="main"]/article[*]/div/div[1]/a/img/@src')
# 打印标题及图片地址
for title,image in zip(title, image):
    print(title.text,image)

结果:

image-20211223114318574

使用CSS选择器解析

对于熟悉 CSS 选择器和 JavaScript 的开发者来说,通过 CSS 选择器获取页面元素可能是更为简单的选择,因为浏览器中运行的 JavaScript 本身就可以document对象的querySelector()和querySelectorAll()方法基于 CSS 选择器获取页面元素。在 Python 中,我们可以利用三方库beautifulsoup4或pyquery来做同样的事情。Beautiful Soup 可以用来解析 HTML 和 XML 文档,修复含有未闭合标签等错误的文档,通过为待解析的页面在内存中创建一棵树结构,实现对从页面中提取数据操作的封装。可以用下面的命令来安装 Beautiful Soup。

pip install beautifulsoup4
下面是使用bs4改写的获取豆瓣电影Top250电影名称的代码。

import bs4
import requests

for page in range(1, 11):
resp = requests.get(
url=f'https://movie.douban.com/top250?start={(page - 1) * 25}',
headers={'User-Agent': 'BaiduSpider'}
)

创建BeautifulSoup对象

soup = bs4.BeautifulSoup(resp.text, 'lxml')
# 通过CSS选择器从页面中提取包含电影标题的span标签
title_spans = soup.select('div.info > div.hd > a > span:nth-child(1)')
# 通过CSS选择器从页面中提取包含电影评分的span标签
rank_spans = soup.select('div.info > div.bd > div > span.rating_num')
for title_span, rank_span in zip(title_spans, rank_spans):
    print(title_span.text, rank_span.text)

关于 BeautifulSoup 更多的知识,可以参考它的官方文档

几种解析方式的比较

解析方式 对应的模块 速度 使用难度 备注
正则表达式解析 re 困难 常用正则表达式 在线正则表达式测试
XPath解析 lxml 一般 需要安装C语言依赖库 唯一支持XML的解析器
CSS选择器解析 bs4 / pyquery 不确定 简单

说明BeautifulSoup可选的解析器包括:Python标准库中的html.parserlxml的HTML解析器、lxml的XML解析器和html5lib