这里写目录标题

  • 一、获取文档树对象
    • 二、文本转化文档树对象
      • 文件转化文档树对象
      • 节点、元素、属性、内容
      • 路径表达式
      • 通配符
      • 谓语
      • 多个路径
      • 函数
      • 实战信息
    • ↓ ↓ ↓ 加下方名片找我,直接拿源码还有案例 ↓ ↓ ↓

一、获取文档树对象

通过Xpath 获取文档的对象,获取到对象后,可以通过文档的对象去去获取到树中的元素。

二、文本转化文档树对象

def strToEleObj():doc = '''<div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签</ul></div>'''# 把文本转换成一个文档树对象html = etree.HTML(doc)result = etree.tostring(html)print(str(result, 'utf-8'))

文件转化文档树对象

def fileToEleObj():# 读取外部文件 index.htmlhtml = etree.parse('./index.html')# pretty_print=True 会格式化输出result = etree.tostring(html, pretty_print=True)  # pretty_print=True 会格式化输出print(result)

节点、元素、属性、内容

xpath 的思想是通过 路径表达 去寻找节点。节点包括元素,属性,和内容

路径表达式

/ 根节点,节点分隔符,
// 任意位置
. 当前节点
… 父级节点
@ 属性

例子:

from lxml import etree
'''路径表达式
'''
def get_el_list():doc = '''<div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签</ul></div>'''# 把文本转换成一个文档树对象html = etree.HTML(doc)# 获取当前节点print('获取当前节点---> ', html.xpath('.'))# 获取 根节点 标签 ,当前元素无根节点 通过 打印 etree.tostring(html) ,会发现根节点为 <html> </html> 包裹的内容 ,上一行获取的当前节点为 htmlprint('获取 根节点 标签---> ', html.xpath('/'))# 获取 li 标签print('获取 li 标签---> ', html.xpath('//li'))# 获取 li 下的 a 标签属性print('获取li下的 a 标签属性----> ', html.xpath('//li/a/@href'))# 获取 p 标签 ,此标签不存在 返回结果为空数组print('获取 p 标签----> ', html.xpath('//p '))

输出结果

获取当前节点--->  [<Element html at 0x2a989854200>]
获取 根节点 标签--->  []
获取 li 标签--->  [<Element li at 0x2a9898ece40>, <Element li at 0x2a9899240c0>, <Element li at 0x2a989924180>, <Element li at 0x2a9899241c0>, <Element li at 0x2a989924200>]
获取li下的 a 标签属性---->  ['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']
获取 p 标签---->  []
  1. 将doc 转换成 文档对象后,为 包裹的内容;故获取到的当前的节点对象为HTML;
  2. 当前节点为HTML,无根节点故返回为空数组即:[];
  3. 查询不存在的节点时,返回空数组即:[]

通配符

*   任意元素
@*  任意属性
node()  任意子节点(元素,属性,内容)

例子:


'''通配符
'''
from lxml import etree
def get_el_by_anyChar():doc = '''<div><ul class="ul" ><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签</ul></div>'''# 把文本转换成一个文档树对象html = etree.HTML(doc)# 获取 ul 下的所有子节点print('获取 ul 下的所有子节点---> ', html.xpath('//ul/node()'))# 获取 任意元素[所有的]print('获取 ul 下 任意元素[所有的]---> ', html.xpath('//ul/*'))# 获取 任意属性 [所有的]print('获取 ul 下 任意属性[所有的]---> ', html.xpath('//ul/@*'))

输出结果

获取 ul 下的所有子节点--->  ['\n                       ', <Element li at 0x1d4792b5e80>, '\n                       ', <Element li at 0x1d4792b5e00>, '\n                       ', <Element li at 0x1d4792b5f00>, '\n                       ', <Element li at 0x1d4792b5f40>, '\n                       ', <Element li at 0x1d4792b5ec0>, ' 闭合标签\n                   ']
获取 任意元素--->  [<Element li at 0x1d47928dd80>, <Element li at 0x1d4792b5e80>, <Element li at 0x1d4792b5fc0>, <Element li at 0x1d4792b5e00>, <Element li at 0x1d4792b5f00>]
获取 任意属性--->  ['ul']

谓语

//a[n] n为大于零的整数,代表子元素排在第n个位置的<a>元素
//a[last()]   last()  代表子元素排在最后个位置的<a>元素
//a[last()-]  和上面同理,代表倒数第二个
//a[position()<3] 位置序号小于3,也就是前两个,这里我们可以看出xpath中的序列是从1开始
//a[@href]    拥有href的<a>元素
//a[@href='www.baidu.com']    href属性值为'www.baidu.com'的<a>元素
//book[@price>2]   price值大于2的<book>元素

例子;

from lxml import etree
def get_el_by_wei():doc = '''<div><ul class="ul" ><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签</ul></div>'''# 把文本转换成一个文档树对象html = etree.HTML(doc)# 获取第一个 li / a 元素 里面的文本print('获取第一个 ---> ', html.xpath('//li[1]/a/text()'))# 获取最后一个 li / a 元素 里面的文本print('获取最后一个 ---> ', html.xpath('//li[last()]/a/text()'))# 获取倒数第二个 li / a元素 里面的文本print('获取 倒数第二个---> ', html.xpath('//li[last()-1]/a/text()'))# 获取位置序号小于3,也就是前两个 li / a元素 里面的文本print('获取位置序号小于3 ---> ', html.xpath('//li[position()<3]/a/text()'))# 获取拥有href的<a>元素下的文本print('获取第一个 ---> ', html.xpath('//a[@href]/text()'))# 获取 a 标签下 href = link3.html的a元素下的文本 注意 不是 == 而是 =print('获取 a 标签下 href = link3.html的<a>元素---> ', html.xpath('//a[@href="link3.html"]/text()'))# 获取 ul class == ul 的print('获取 ul class == ul  ---> ', html.xpath('//ul[@class="ul"]'))

多个路径

用| 连接两个表达式,可以进行 或匹配

//book/title | //book/price

例子;

from lxml import etree
def get_el_mutil_path():doc = '''<div><ul class="ul" ><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签</ul></div>'''# 把文本转换成一个文档树对象html = etree.HTML(doc)# 获取li 下 class = item-inactive 或者 item-1print('获取li 下 class = item-inactive 或者 item-1 ---> ', html.xpath('//li[@class="item-inactive"] | //li[@class="item-1"] '))

输出结果;

获取li 下 class = item-inactive 或者 item-1 --->  [<Element li at 0x1b490955f40>, <Element li at 0x1b490966200>, <Element li at 0x1b490966180>]

函数

contains(string1,string2)
starts-with(string1,string2)
# 文本
text()
# 最后一个
last()
# 位置
position()
# 回去所有节点
node()
'''函数
'''
from lxml import etree
def get_el_func():doc = '''<div><ul class="ul" ><li class="item-0 active"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签</ul></div>'''# 把文本转换成一个文档树对象html = etree.HTML(doc)# 匹配 class 包含 active 的 元素print(html.xpath("//*[contains(@class,'active')]"))# 获取所有 li / a 文本print(html.xpath("//li/a/text()"))# 获取最后一个 li / a 文本print(html.xpath("//li[last()]/text()"))# 获取位置为1的li /a 文本 ,节点时从1开始 而不是0print(html.xpath("//li[position()=1]/a/text()"))

输出结果;

[<Element li at 0x23ea36d0400>, <Element li at 0x23ea36d0180>]
['first item', 'second item', 'third item', 'fourth item', 'fifth item']
[' # 注意,此处缺少一个 ']
['first item']

实战信息

获取某电影网站电影名称、简单描述、图片

import requests
from lxml import etree'''获取电影信息列表
'''
def get_moive_info_list(url):# 定义头部信息headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}res = requests.get(url, headers=headers)# res.text 返回的是 文本html = res.textprint('输出响应信息->',html)# 将文本转换成文档对象selector = etree.HTML(html)# 返回是电影名列表title_list = selector.xpath('//a[@class="pic-pack-outer"]/h3/text()')print('电影名称列表:',title_list)# 获取简单描述desc_list = selector.xpath('//a[@class="pic-pack-outer"]/p/text()')print('电影名称简单描述:', desc_list)# 图片img_list = selector.xpath('//a[@class="pic-pack-outer"]/img/@src')print('图片列表:', img_list)if __name__ == '__main__':url = 'https://xxxxxxx/vod/list/n_1_t_25/o1p1.html'get_moive_info_list(url)

输出结果

输出响应信息-> <!DOCTYPE html>
·······
</body>
</html>
电影名称列表: ['辣妈犟爸', '五月梨花香', '岁岁平安',.....]
电影名称简单描述: ['年轻村官奋斗历程', '脱贫致富振兴家乡', .....]
图片列表: ['https://image11.m1905.cn/uploadfile/2022/0804/thumb_1_150_203_20220804094442559303.jpg',  .... 'https://image11.m1905.cn/uploadfile/2016/0926/thumb_1_150_85_20160926105222739343.jpg']

↓ ↓ ↓ 加下方名片找我,直接拿源码还有案例 ↓ ↓ ↓

Python爬虫-xpath方法爬虫技术分享,更高效,代码简洁!相关推荐

  1. 【视觉目标跟踪最高峰】VOT Challenge 2017 亚军北邮团队技术分享(附代码)

    视觉跟踪领域国际顶级赛事 Visual-Object-Tracking Challenge (VOT) 2017年结果出炉,结合传统滤波及深度学习的方案取得最佳成绩.本文是第二名北京邮电大学代表团队的 ...

  2. chatgpt赋能python:Python断点调试指南:让调试更高效

    Python断点调试指南:让调试更高效 在Python编程中,调试是一个必不可少的环节.当我们面临代码出现错误或程序不按预期运行时,如何快速找到问题,解决它们呢?这时候断点调试就发挥了重要的作用.本篇 ...

  3. python课设总结_Python技术分享课总结:用Python模拟知乎自动登录

    原标题:Python技术分享课总结:用Python模拟知乎自动登录 Python语言是由Guido van Rossum大牛在1989年发明,它是当今世界最受欢迎的计算机编程语言之一,也是一门&quo ...

  4. 学习Java有什么好的方法?怎么学习更高效?

    一个好的学习方法(应该怎么学习更高效) 编程思想就是编程思路,有很多同学问我:老师,我现在听课能听懂,但是你让我解决一个实际的问题,我不会,不知道该怎么下手!!! 千万不要照抄代码,没用.或者说作用很 ...

  5. Python使用Xpath轻松爬虫(脑残式)

    1.在PyCharm安装lxml. 2.找到源码 3.F12.copy源码的xpath 4.代码 from lxml import etree import requestswb_data = req ...

  6. 基于python的搜索引擎论文_技术分享 - 基于python构建搜索引擎系列——(四)检索模型...

    构建好倒排索引之后,就可以开始检索了. 检索模型有很多,比如向量空间模型.概率模型.语言模型等.其中最有名的.检索效果最好的是基于概率的BM25模型. 给定一个查询Q和一篇文档d,d对Q的BM25得分 ...

  7. 【华为云技术分享】低代码开发平台发展趋势:低代码——炒作还是趋势?

    在<人月神话>的开篇提到焦油坑,没有别的场景比巨兽在焦油坑中垂死挣扎的场面更令人震撼.上帝见证着恐龙.猛犸象.剑齿虎在焦油中挣扎.他们挣扎的越是猛烈,焦油纠缠的越紧,没有任何猛兽足够壮烈或 ...

  8. 【华为云技术分享】一行代码就能写一个日志打印组件,你信吗?为你揭晓LiteOS中日志打印组件的核心

    1. 做实验引发的思考 在学习LiteOS日志打印组件使用的时候,我记录了一篇博客:atiny_log | LiteOS 物联网操作系统中的日志打印组件使用分享,关于实验的具体内容,请阅读这篇博客. ...

  9. 微信管制下,如何让你的H5诱导分享更高效?

    http://www.zcool.com.cn/article/ZNDg2NTk2.html

最新文章

  1. converter 冷迁
  2. 如何正确访问Redis中的海量数据?服务才不会挂掉!
  3. php const 字符串,我可以使用字符串连接在PHP中定义一个类CONST吗?
  4. 初读JavaScript DOM编程艺术(一)
  5. 只有ajax会跨域吗_为什么跨域Ajax是安全问题?
  6. 好未来AI Lab-文本检测方法分析
  7. The Classic IQ Test
  8. python基础练习题30道
  9. librdkafka 封装的C++类
  10. qgis比例尺级别设置
  11. Qt QML 模块化管理(三)—— qmldir的化繁为简
  12. druid emitter 监控模块
  13. 摄影知识系列讲座 - 第一章《光圈、快门篇》
  14. Hashtable、HashMap 与 HashTable区别、HashMap、Hashtable和TreeMap、 LinkedHashMap
  15. 病毒感染高峰期错过考研怎么办?社科院与杜兰金融管理硕士项目是你强大的后盾
  16. html如何实现3d动画,基于webGL和HTML5的网页3D动画的设计与实现.pdf
  17. 无间狱无服务器信息,无间狱打不动了,分享一些想法(不开99流),多图
  18. Git问题:右键没有Git Bash Here的解决办法
  19. 《智能制造》赵亚波《工业控制计算机》2002年15卷第3期
  20. 17.200种鸟类图片分类

热门文章

  1. Android 和dialog 防录屏功能失效,游戏防录屏功能失效.
  2. MySQL5.7版本修改了my.ini配置文件后mysql服务无法启动问题
  3. java螺旋方阵_一类螺旋方阵问题的算法分析与实现
  4. 智能音箱 之 功放与扬声器(喇叭)的匹配关系
  5. 自我激励的20个方法
  6. 向着未知的领域继续前行
  7. 新年快乐ctf_2013年新年快乐
  8. 【自学php】如何用 PHP 制作个人博客网站:一步步实现从零到一
  9. 攻城狮与程序猿的区别
  10. 【双周报】LBTC双周报