xpath 解析网页
什么是xpath ?
xml: 可扩展标记语言,用来传输和存储数据。他的标签没有预定义,要自己定义标签。 与html的区别: html是用来显示数据的,html的标签是固定的
xpath: 是一门在xml 文档中查找信息的语言,这里,我们可以用xpath来查找html文档,它是一种路径表达式
常用的路径表达式:
表达式 | 含义 |
---|---|
// | 不考考虑位置的查找 |
./ | 从当前节点开始往下查找 |
. . | 从当前节点的父节点往下找 |
@ | 选取属性 |
实例:
表达式 | 含义 |
---|---|
/bookstore/book | 选取根节点 bookstore 下的所有 直接子节点 book |
//book | 选取任意位置的 book 节点 |
bookstore//book | 选取 bookstore 下面所有的book 节点,不管是不是直接子节点。 |
//@lang | 选取所有名为 lang 的属性的标签 |
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取 bookstore 下的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取 |
/bookstore/book[position()< 3] | 选取bookstore下的最前面的两个book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang=‘eng’] | 选取所有 lang 属性值为 eng 的 title 元素 |
/bookstore/book[price>35.00] | 选取 bookstore 下的所有 price属性值大于 35.00的 book |
/bookstore/book[price>35.00]//title | 选取 bookstore 下的所有 price属性值大于 35.00的 book 下的title |
安装xpath插件到浏览器。
安装成功后,启动和关闭。ctrl+shift+x
左边是路径表达式,右边是结果,如果路径写对了的话就会显示。
下面在谷歌浏览器的百度的首页进行实验www.baidu.com
看看能不能定位到想要的东西
属性定位
//input[@name='wd']
定位到搜索框
//input[@class='btn self-btn bg s_btn']
定位到百度一下这个按钮
层级定位,索引定位
//div[@id='head_wrapper']/div[2]/a[1]
注意:索引从1开始
//div[@id='head_wrapper']//a[@class='toindex']
双斜杠代表下面的所有a标签
逻辑运算
//input[@type="hidden" and @name="f"]
当一个属性不足以限制的时候,可以用多个
模糊匹配
contains://input[contains(@class,"s")]
有class属性并且属性值里面有一个s
ret3 = tree.xpath('//li[contains(text(),"心")]')
选取内容有“心”字的
starts-with://input[starts-with(@class, "s")]
class属性以s开头
取文本
//div[@id="u_sp]/a[6]/text()
获取节点里面的内容
//div[@id="u_sp"]//text()
获取节点里面,不带标签的所有内容
//div[@id="u_sp"]/string()
得到所指元素的所有节点文本内容,这些文本讲会被拼接成一个字符串。
取属性
//div[@id='u_sp']/a[6]/@href
选取href属性
看代码中的使用:爬取好段子
http://www.haoduanzi.com/category/?44-2.html
就是这个网
这个的第三方库应该前面已经装了,没有装的话就pip install lxml
如果第一次看,不知道怎么切换国内源的话清移步——>pip 切换国内源
下面看看这个网站,分析一下
我们看到了页码的变化,如果想爬取多页可以设计拼接url,这里我就只爬一页就好了,主要是看xpath怎么解析网页,这个段子其实没什么意义,只是告诉大家分析的方法。
在网页中打开刚才的插件,然后 F12 检查元素,
我们来看看路径是什么,
- 首先找到 class属性位
list-box
的标签 - 再找到他下面的
li
标签 - 里标签里面有两个
div
我们要的是第二个,所以是div[2]
注意之前说过,索引从1开始。 - 然后 找到
a
标签, - 最后定位到
p
标签 - 写一下就这样
//ul[@class="list-box"]//li/div[2]/a/p
下面看整个代码。
记得,导入库 form lxml import etree
import urllib.request
import urllib.parse
from lxml import etree
# 先按套路,构建请求对象,发送请求,获取相应,这次用urllib 实现,想用requests 实现也可以
url = 'http://www.haoduanzi.com/category/?44-1.html'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request).read().decode()
# 开始解析
## 先生成一个解析对象
tree = etree.HTML(response)
# 这里把刚才浏览器里的解析路径复制过来
ret = tree.xpath('//ul[@class="list-box"]//li/div[2]/a/p')
# ret是一个列表,存放每一条内容
#写入文件
for p in ret:
with open('duanzi.html', 'a', encoding='utf8') as f:
## 刚才只是解析到标签,但是我们要获取内容,所以
## string()函数会得到所指元素的所有节点文本内容
## 这些文本讲会被拼接成一个字符串。括号里加 (.) 表示当前节点
f.write('<li>'+p.xpath('string(.)')+'</li>'
这样就成功了,看看结果吧
总结一下:
- 我们还是按套路请求到了相应,
- 通过
etree.HTML()
方法构建了一个可解析的对象(转了类型), - 通过浏览器插件写好 解析路径,再写在
tree.xpath()
方法里 - 写入文件的是,我们要提取 节点的内容,并通过字符串写入,我么使用了xpath 里的
string()
最后简单说一下 text() 和 string()
text(),它仅仅返回所指元素的文本内容。
string() 函数会得到所指元素的所有节点文本内容,这些文本讲会被拼接成一个字符串。
个人觉得 xapth 还挺好用的,明天我们还会学另一种解析的方法,bs4解析
又到了卑微要赞的时间,如果觉得讲的还可以,可以学到些什么的话,就点个赞再走吧,欢迎路过的大佬评论指正,如果有什么问题欢迎评论提问。
最近有不少小伙伴私聊我了吖~~~开心,我会尽量每天更新一篇的,然后,,爬虫主要还是要多练习,我在这里主要是讲使用方法,所以还是希望各位小伙伴自己多写写代码练习,有爬取不下来的问题后,就继续学习,等到后面再去爬那个网站。😄😄😄 开心脸