一、简介
- xpath 浏览器插件,安装之后可以直接在浏览器输入
xpath
进行测试
# 开关快捷键 windows: Ctrl-Shift-X Mac: Command-Shift-X
- 简单流程
# 1、安装 lxml 库 $ pip install lxml # 或使用国内源 $ pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple # 2、导入 lxml.etree from lxml import etree # 3、解析本地文件:etree.parse() html_tree = etree.parse('xxx.html') # 4、解析服务器响应数据:etree.HTML() html_tree = etree.HTML(response.read().decode('utf-8')) # 5、xpath路径 html_tree.xpath('xpath路径')
xpath
严格遵守HTML
规范,所有标签必须闭合(结束符)。
二、使用
- xpath 语法入门,使用案例简单列举:
路径表达式案例 | 含义 |
// |
查找所有子孙节点,不考虑层级关系 |
/ |
直接找子节点 |
//div[@id] |
查询有 id 属性的 div 标签 |
//@class |
获得所有带 class 属性标签的 class 属性值 |
//div[contains(@id, "he")] |
查询 id 属性包含 he 的 div 标签 |
//div[starts-with(@id, "he")] |
查询 id 属性以 he 开头的 div 标签 |
//div/h1/text() |
获得 div 标签内 h1 标签的内容 |
//div[@id="head" and @class="one"] |
查找 id 属性为 head 同时 class 属性为 one 的 div 标签 |
//div[@id="head"] | //div[@id="one"] |
查找 id 属性为 head 或 id 属性为 one 的 div 标签 |
- 本地测试文件
test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Document</title> </head> <body> <ul> <li>北京</li> <li>上海</li> <li>深圳</li> <li>武汉</li> </ul> <ul> <li>大连</li> <li>沈阳</li> <li>长沙</li> </ul> </body> </html>
- 本地案例
# 导入 lxml.etree from lxml import etree # 解析本地文件(远程网页内容按上面使用流程替换就行) tree = etree.parse('test.html') # 查找 ul 下面带 id 属性的 li 标签 li_list = tree.xpath('//ul/li[@id]/text()') # ['北京', '上海', '深圳', '武汉'] li_list = tree.xpath('//li[@id]/text()') # ['北京', '上海', '深圳', '武汉'] # 查找 ul 下面 id 属性为 l1 的 li 标签 li_list = tree.xpath('//li[@id="l1"]/text()') # ['北京'] # 获取 ul 下面 id 属性为 l1 的 li 标签的内容 li_list = tree.xpath('//li[@id="l1"]/text()') # ['北京'] # 查找 ul 下面 id 属性为 l1 的 li 标签的 class 属性值 li_list = tree.xpath('//li[@id="l1"]/@class') # ['c1'] # 查找 id 属性中包含 3 的标签 li_list = tree.xpath('//ul/li[contains(@id, "3")]/text()') # ['深圳'] # 查找 id 属性中以 l 开头的标签 li_list = tree.xpath('//ul/li[starts-with(@id, "l")]/text()') # ['北京', '上海', '深圳', '武汉'] # 查找 id 属性为 l1 和 class 属性为 c1 的标签 li_list = tree.xpath('//ul/li[@id="l1" and @class="c1"]/text()') # ['北京'] # 查找 id 属性为 l1 或 id 属性为 l2 的标签 li_list = tree.xpath('//ul/li[@id="l1" | @class="c1"]/text()') # 错误写法 li_list = tree.xpath('//ul/li[@id="l1"]/text() | //ul/li[@id="l2"]/text()') # ['北京', '上海'] # 输出 # print(li_list) # print(len(li_list))
- 远程案例
# 使用 urllib import urllib.request # 使用 lxml from lxml import etree # 定义 header headers = { # UA 最基本的防爬识别 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' } # 1、定义一个 https 的 url url = 'https://www.baidu.com' # 2、定义一个 Request 对象,urlopen 方法并不能直接带 header。 # 细节:为什么这里需要写 url=url