一、XPATH是什么?干什么用的?
xpath(XML Path Language)是一门在XML和HTML文档中查找信息的语言,可用来在XML和HTML文档中对元素和属性进行遍历,用来确定XML文档中某部分位置的语言。
目前浏览器都有对应的xpath扩展程序
- Chrome插件XPath Helper。
- Firefox插件Try XPath。
安装插件
chrome浏览器的扩展程序下载需要翻墙,因此我寻找了另外一个安装方法,如下具体见 https://www.cnblogs.com/ubuntu1987/p/11611111.html
.首先在以下链接下载XPath Helper插件,链接:https://pan.baidu.com/s/1Ng7HAGgsVfOyqy6dn094Jg
提取码:a1dv
2.插件下载完成后解压,然后在解压文件中找到2.0.2_0.crx文件,并将其后缀crx改成rar,如下所示
解压后打开Chrome浏览器的扩展程序,打开开发者模式,加载已解压的扩展程序如下
4.关于使用
重启浏览器,点击右上角的坐标出现下图所示
1.选取节点:
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似
2.谓语:
谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中。 在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
注意: 下标是从1开始的 ,不是从0开始的。
| 路径表达式 | 描述 |
| /bookstore/book[1] | 选取bookstore下的第一个子元素 |
| /bookstore/book[last()] | 选取bookstore下的最后一个个book元素。 |
| bookstore/book[position()<3] | 选取bookstore下前面两个子元素。 |
| //book[@price] | 选取拥有price属性的book元素 |
| //book[@price=10] | 选取所有属性price等于10的book元素 |
3.通配符
*表示通配符。
| 通配符 | 描述 | 示例 | 结果 |
| * | 匹配任意节点 | /bookstore/* | 选取bookstore下的所有子元素。 |
| @* | 匹配节点中的任何属性 | //book[@*] | 选取所有带有属性的book元素。 |
4.选取多个路径:
通过在路径表达式中使用“|”运算符,可以选取若干个路径。 示例如下:
``` //bookstore/book | //book/title
Python爬虫之xpath的基本使用(解析HTML详细介绍)可参考https://blog.csdn.net/xunxue1523/article/details/104584886
lxml库
lxml是一个HTML/XML的解析器,主要的功能是如何解析和提取 HTML/XML 数据。
lxml和正则一样,也是用C实现的,是一款高性能的 Python HTML/XML解析器,我们可以利用之前学习的XPath语法,来快速的定位特定元素以及节点信息。
lxml python官方文档:http://lxml.de/ index.html需要安装c语言库,可使用pip安装: pip install lxml
基本使用:
通过字符串转换成html格式
用lxml解析html
利用etree.HTML解析字符串
将字符串解析从html格式的文件, 经过处理后,部分缺失的节点可以自动修复,并且还自动添加了 body、html 节点。
Python源码:
from lxml import etree
text='''
<div class="lg_tbar_l">
<a href="https://www.lagou.com/" class="logo"></a>
<ul class="lg_tbar_tabs">
<li >
<a href="https://www.lagou.com/" data-lg-tj-id="5i00"
data-lg-tj-no="idnull" data-lg-tj-cid="idnull">首页</a>
</li>
<li >
<a href="https://www.lagou.com/gongsi/" data-lg-tj-id="5j00"
data-lg-tj-no="idnull" data-lg-tj-cid="idnull" data-lg-tj-track-code="index_company">公司</a>
</li>
<li>
<a href="https://xiaoyuan.lagou.com/" data-lg-tj-id="19xc" data-lg-tj-no="idnull"
data-lg-tj-cid="idnull" target="_blank" data-lg-tj-track-code="index_campus">校园招聘
</a>
</li>
<li >
<a href="https://www.lagou.com/zhaopin/" data-lg-tj-id="4s00" data-lg-tj-no="idnull"
data-lg-tj-cid="idnull" data-lg-tj-track-code="index_zhaopin">职位
</a>
</li>
<li >
<a href="https://yanzhi.lagou.com/"
data-lg-tj-id="ic00" data-lg-tj-no="idnull" data-lg-tj-cid="idnull"
data-lg-tj-track-code="index_yanzhi">言职</a>
</li>
<li>
<a href="https://kaiwu.lagou.com/" data-lg-tj-id="1mua" data-lg-tj-no="idnull"
data-lg-tj-cid="idnull" data-lg-tj-track-code="index_kaiwu" target="_blank">课程<span class="tips-new">new</span></a>
</li>
<li>
<a href="https://www.lagou.com/app/download.html" target="_blank">APP</a>
</li>
</ul>
</div>
'''
html = etree.HTML(text)
result = etree.tostring(html)
print(result.decode('utf-8'))
解析html文件
from lxml import etree
html = etree.parse('csdn.html', etree.HTMLParser(encoding='utf-8'))
result = etree.tostring(html,encoding='utf-8')
print(result.decode('utf-8'))
获取某个标签的内容(后续都使用Tencent.html 练习文件见末尾)
注意,获取li标签的所有内容,li后面就不用再加正斜杠,否则报错
//li xpath返回的是一个列表
from lxml import etree
html = etree.parse('tencent.html', etree.HTMLParser(encoding='utf-8'))
html_data = html.xpath('//li')
for i in html_data:
print(etree.tostring(i,encoding='utf-8').decode('utf-8'))
# 4.获取所有class id的值
aList = html.xpath('//div[@class="qr-code"]/@id')
for a in aList:
print ("https://careers.tencent.com/jobdesc.html?postId="+a)
#
https://careers.tencent.com/jobdesc.html?postId=1318796892787712000
https://careers.tencent.com/jobdesc.html?postId=1318825301697896448
https://careers.tencent.com/jobdesc.html?postId=1318887083753873408
https://careers.tencent.com/jobdesc.html?postId=1308047506302574592
https://careers.tencent.com/jobdesc.html?postId=1329746102546604032
https://careers.tencent.com/jobdesc.html?postId=1329654375789895680
https://careers.tencent.com/jobdesc.html?postId=1242636410821808128
https://careers.tencent.com/jobdesc.html?postId=1328961232517996544
https://careers.tencent.com/jobdesc.html?postId=1275971541930090496
https://careers.tencent.com/jobdesc.html?postId=1285478800217350144
文本获取方法
有两种方法:一是获取文本所在节点后直接获取文本,二是使用 //。
第二种方法会获取到补全代码时换行产生的特殊字符,推荐使用第一种方法,可以保证获取的结果是整洁的。
# 第一种
from lxml import etree
html_data = html.xpath('//li[@class="item-1"]/a/text()')
print(html_data)
# 第二种
html_data = html.xpath('//li[@class="item-1"]//text()')
print(html_data)
#案例 :获取职位信息 存文本
#在某个标签下,再执行xpath函数, 获取这个标签下的子孙元素
#那么应该在//之前加一个点,代表是在当前元素下获取
aList = html.xpath('//a[@class="recruit-list-link"]')
positions=[]
for a in aList:
#print(etree.tostring(a,encoding='utf-8').decode('utf-8'))
#print ("https://careers.tencent.com/jobdesc.html?postId="+a)#
title=a.xpath('./h4//text()')[0]
address=a.xpath('./p[@class="recruit-tips"]/span[2]//text()')[0]
category=a.xpath('./p[@class="recruit-tips"]/span[3]//text()')[0]
time=a.xpath('./p[@class="recruit-tips"]/span[4]//text()')[0]
responsibilities=a.xpath('./p[@class="recruit-text"]//text()')[0]
position={
'title':title,
'address':address,
'category':category,
'time':time,
'responsibilities':responsibilities
}
positions.append(position)
print(positions)
练习所用的数据https://download.csdn.net/download/sereasuesue/15267619