python网络爬虫
使用XPath进行网页解析
使用Xpath解析网页
- Xpath介绍
XML路径语言(XML Path Language),它是一种基于XML的树状结构,在数据结构树中找寻节点,确定XML文档中某部分位置的语言。
需要把源文件转成树状结构,再对树状结构应用相应的xpath查询语句
- 基本语法
使用Xpath需要从lxml库中导入etree模块,还需使用HTML类对需要匹配的HTML对象进行初始化(XPath只能处理文档的DOM表现形式)。HTML类的基本语法格式如下。
lxml.etree.HTML(text, parser=None, *, base_url=None)
参数:
参数名称 | 说明 |
---|---|
text | 接收str。表示需要转换为HTML的字符串。无默认值 |
parser | 接收str。表示选择的HTML解析器。无默认值 |
base_url | 接收str。表示设置文档的原始URL,用于在查找外部实体的相对路径。默认为None |
- 基本语法
Xpath使用类似正则的表达式来匹配HTML文件中的内容,常用匹配表达式如下
表达式 | 说明 |
---|---|
nodename | 选取nodename节点的所有子节点 |
/ | 从当前节点选取直接子节点 |
// | 从当前节点选取子孙节点 |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
- 谓语
Xpath中的谓语用来查找某个特定的节点或包含某个指定的值的节点,谓语被嵌在路径后的方括号中,如下。
表达式 | 说明 |
---|---|
/html/body/div[1] | 选取属于body子节点下的第一个div节点 (没有零从一开始) |
/html/body/div[last()] | 选取属于body子节点下的最后一个div节点 |
/html/body/div[last()-1] | 选取属于body子节点下的倒数第二个div节点 |
/html/body/div[positon()< 3] | 选取属于body子节点下的下前两个div节点 |
/html/body/div[@id] | 选取属于body子节点下的带有id属性的div节点 |
/html/body/div[@id=”content”] | 选取属于body子节点下的id属性值为content的div节点 |
/html /body/div[xx>10.00] | 选取属于body子节点下的xx元素值大于10的节点 |
html.xpath('/html/body/header/div/nav/ul/li')#查找该节点下所有元素
html.xpath('/html/body/header/div/nav/ul/li[1]')#查找该节点下第一个元素
查找该字段
html.xpath('/html/body/header/div/nav/ul/li/a[@target="_blank"]')
>>>[<Element a at 0x26d252da948>]
提取内容
html.xpath('/html/body/header/div/nav/ul/li/a[@target="_blank"]/text()')
>>>['认证证书']
简化xpath查询语言
- 省略/html/body直接查找根节点
html.xpath('//header/div/nav/ul/li')
- 若某节点下的节点只出现了一次(可查询次数),也可简化
html.xpath('//*[@id="menu"]/li/a')#id="menu"只出现一次
- 功能函数
Xpath中还提供功能函数进行模糊搜索,有时对象仅掌握了其部分特征,当需要模糊搜索该类对象时,可使用功能函数来实现,具体函数如下。
功能函数 | 示例 | 说明 |
---|---|---|
starts-with | //div[starts-with(@id,”co”)] | 选取id值以co开头的div节点 |
contains | //div[contains(@id,”co”)] | 选取id值包含co的div节点 |
and | //div[contains(@id,”co”)andcontains(@id,”en”)] | 选取id值包含co和en的div节点 |
text() | i[contains(text(),”first”)] | 选取节点文本包含first的div节点 |
import requests
from lxml import etree
url = 'https://weixin.sogou.com/'
rqq = requests.get(url)
html = etree.HTML(rq.content,etree.HTMLParser(encoding='utf-8'))
html.xpath('//*[@id="topwords"]/li/a[@title]/text()')
>>>['丰田回应投资滴滴',
'华为在美提起诉讼',
'贝佐斯前妻捐赠',
'移动推首批5G手机',
'新iPod touch',
'稀土反制',
'阿里香港二次上市',
'范冰冰无名指钻戒',
'出生6天捐献器官',
'广东暴雨现龙吸水']
[html.xpath('//*[@id="topwords"]/li['+str(i)+']/a[@title]/text()') for i in range(1, 11)]
>>>['丰田回应投资滴滴',
'华为在美提起诉讼',
'贝佐斯前妻捐赠',
'移动推首批5G手机',
'新iPod touch',
'稀土反制',
'阿里香港二次上市',
'范冰冰无名指钻戒',
'出生6天捐献器官',
'广东暴雨现龙吸水']
可从开发者工具复制xpath节点