《浅谈解析库XPath,bs4和pyquery》

作者:墨非墨菲非菲

前几天在CSDN看到一篇帖子,题目是“如何让自己像打王者一样发了疯,拼了命,石乐志的学习”。这里面讲到了阶段性反馈机制,我觉得蛮有意思的,正好前两天用python写了一个scrawler爬取了某XXXX软件上面的挑战答题并自动匹配。在解析题库网页的时候碰到了一系列的问题,把三种解析库都回顾了个遍。借着这个兴奋劲儿,决定码一篇python解析库————lxml,bs4,以及pyquery的简要概述。 :happy:
下面仅仅是我个人的回忆和记录,仅供参考,错误之处还请多多指正。

写在前面

以上提到的三个是python语言中最最最常用的三个解析库,解析库是用来提取网页的html信息的。首先要解释一下,网页中如此多的信息,为什么能够被精准的获取到。网页可以分为三大部分————HTML,JavaScrip和CSS,这些要素构成了我们看到的丰富多彩的网页。

解析库基于网页的两类特征,一类是节点树(HTML DOM),一类是css选择器。如果把节点树比作一个家庭,那么它就包含了它爷爷,它老汉(parent),它兄弟(sibling)以及它儿子和孙孙(children)。有了这个节点树,网页里面每一个元素就层级分明的展现了出来。 具体的,构成这棵树的枝节,又包根元素(html),元素(title,body,a…),属性(class,href…)和文本等等。css,即层叠样式表,它有一套属于自己的语法规则,举个例子,选择器(.link)代表了’class=“link”’,(#song)代表了’id=“song”’,(a)代表了’a’的所有节点。
有了上面的规则,每个元素的位置就被唯一确定了下来了,接下来解析库就登上了舞台,使出了元哥般的秀发。

下面是分割线


【解析库一:XPath】

XPath,全名是XML Path Lauguage。拿到一个库,如果有精力和毅力阅读官方文档当然最好,虽然我几乎没有过。知道名字,好像意义不大,所以,直接上干货。

1.初始化

先说说初始化(initition),可被解析的有字符串(string)和html文件(filename.html)。具体的使用方法:
首先要安装lxml库,python CMD:pip install lxml


```python```python
res = '''   <div class="info"><div class="hd"><a href="https://movie.douban.com/subject/1316510/" class=""><span class="title">射雕英雄传之东成西就</span><span class="title"> / 射鵰英雄傳之東成西就</span><span class="other class-1" name="item"> / 东成西就  /  大英雄 (日本)</span></a><span class="playable">[可播放]</span></div></div>'''
from lxml import etree
html = etree.HTML(res) #调用HTML()方法初始化字符串(string)例
html = etree.tostring() #调用tostring()方法可以补全未闭合的标签
print(html.decoding('utf8')) #以字符串的格式打印

文件采用以下方法:

from lxml import etree
html = etree.parse('./text.html',etree.HTMLParser()) #调parse()方法来实例化文件(filename.html)
result = html.xpath('//*') #xpath()里面传入匹配规则

到这里,初始化的方法就说完了(我所知道的,手动狗头保命/滑稽)

2.匹配方法

(1)子节点(/)和子孙节点(//)

例如,我想获取以上res文本中的“射雕英雄传之东成西就”和’a’标签里的网址,
以下涉及到了子节点,子孙节点的选择,属性的匹配,文本和属性值的获取。

movie = html.xpath('//div[@class="info"]//a/span/text()')
url = html.xpath('//div[@class="info"]//a/@href')

(2)获取文本“东成西就”,class属性值有两个,那么就引入了属性多值匹配和多属性匹配

text=html.xpath('//div[@class="info"]//span[contains(@class,"other") and @name="item"]/text()')

3.节点选择

在匹配方法中主要涉及了子节点和子孙节点。接下来还有父节点(parent)和祖父节点(parents)

result = html.xpath('//span[@class="titile"]/../a')

因为xpath默认解析全部符合规则的标签,所以这里就不提及sibling节点。

4.类型

如果可爱的你玩元哥不想成为神仙打架,那么时时刻刻清楚自己的本体在哪是很重要的。如果在运用解析库的时候不想天花乱坠,得时时刻刻清楚下一步输出的文件类型!!!知道类型才知道应该用什么方法。

print(type(result),result,sep='|')
>>><class 'list'>|[<Element div at 0x19804f1d308>]

是列表类型记得迭代,for搞定一切!

5.按序选择

因为同级的标签是有很多的,上面得出了输出文件是list的结论,那么聪明的你一定知道了,它可以切片,我仿佛看到了乐事薯片发出的香甜可口的气息~好了,pia!回到正题,按序选择就是用中括号传入索引获取特定了次序的节点。
注意是从“1”开始
直接上码

result = html.xpath('//li[1]/a/text()')
#可替换的例如:[last()], [last()-1], [positon()<3]等等

6.好了,没有6了

当然,更多详细的关于python的lxml库的使用可以访问网址。
个人的一点小总结,lxml的使用方法和BeautifulSoup是比较接近的,都是依赖于节点树和标签。功能上说得上中规中矩,该有的它都有。一定要说一点优势嘛,它的层级结构是非常清楚的,非常易于阅读。并且直接建立在lxml之上,匹配速度应该算是很快的了(空口说这个速度会不会有些有失公允,让用户感知不强?)。不过关于属性匹配的写法,难免复杂了些。遇到属性多值的匹配还傲娇,必须得用[constains(@class,"…")来进行匹配,多多少少有些复杂。当然,这都是些后话啦。

【解析库二:BeautifulSoup】

一个强大的解析工具BeautifulSoup,借助网页结构和属性来解析网页。最先接触的解析库,本着“国外的月亮更圆”的陋习,在只知道BeautifulSoup的时候,还去硬刚过re,结果被re复杂的匹配规则劝退。顺便说一下,re它长这样:

>data-src = re.findall('<dd>.*?class="star">(.*?)</dd>))$。

手动(黑人脸问好.png),废话不多说,直接上菜。

1.初始化

BeautifulSoup可传入字符串(string),在解析时依赖于解析器,例如’BeautifulSoup(res,‘html.parser’),这里的html.parser就是python内置的标准解析库,执行速度适中,文档容错性强。如果你非要快,'lxml’和’xml’是你的不二选择,不过提前安装好C语言库哦。
首先要安装bs4库,python CMD:pip install bs4

import requests
from bs4 import BeautifulSoup
res = requests.get('https://www.baidu.com/s?ie=UTF-8wd=%E5%B0%8F%E8%AF%B4').text    #获取网页源代码
soup = BeautifulSoup(res,'lxml')     #格式化字符串,依靠lxml析库

2.基本用法

find_all(),顾名思义,查找所有符合条件的元素。它的api如下:
find_all(name,attr,text,**kwargs)
实操环节

items = soup.find('div', class_="c-tabs c-gap-top-small")find('ul').find_all('li)['href']
for item in items[0]:print(item)

以上实例展示了find():查找符合条件的第一个标签,属性的引用需要说明,在python中class为关键字,所以碰到class标签要加上下划线,获取属性值[‘href’] or .get('herf), 文本的获取(.text)/(.string)

3.节点选择

(1)子节点和子孙节点

选取节点元素之后,如果想要获取它的直接子节点,直接调用contents属性或children即可,例如:

print(items.a.contents)

如果要得到子孙节点,可以调用descendants属性。值得一提,descendants会递归查询所有的子孙节点。

(2)父节点和祖父节点

print(items.a.parent)   #父节点
print(items.a.parents)   #祖先节点

(3)兄弟节点

print(items.a.sibling)

哈哈哈,到这里,你以为只是简单的复述几个单词咯?下面才是冷知识点。
next_sibling, previous_sibling, list(enumerate(next_siblings)), list(enumerate(previous_siblings))

4.类型

类型永远是个重点,初次试水记得时时刻刻用type()函数查询,直接捡现的:

print(type(soup))
>>><class 'bs4.element.Tag'>

在没有被text之前,它始终是个bs4.element.Tag类型,这也意味着,能够在bs4.element.Tag上面套娃————实现嵌套功能:find(‘ul’).find_all('li)。

5.CSS选择器

BeautifulSoup还提供了css选择器,只需要调用select()方法,传入相应的css选择即可。并且,它继承了BeautifulSoup的bs4.element.Tag类型,支持嵌套功能。举个例子:

items = soup.find(‘div’, class_=“c-tabs c-gap-top-small”)find(‘ul’).find_all('li)[‘href’] #find()写法
items = soup.select(‘div[contains(@class=“c-tabs”)]/ul/li@href’) #select()写法


6.好了,BeautifulSoup的基本用法就介绍完了

最后来点小总结。聪明的你一定会发现,BeautifulSoup的篇幅足够短,因为它足够easy和brief。而且它向左兼容节点,向右能用css。给它个“好看又能打”的称号一点也不为过了。从初始化开始,它的文件类型始终是<class ‘bs4.element.Tag’>,你可以随意嵌套。碰到单个文件,直接打印;多个文件,迭代打印。唯一需要注意的是class_="…",一定不要忘记!

【解析库三:pyquery】

接下来,让我们来感受一下这个偏科生————pyquery的强大之处。

1.初始化

首先安装pyquery库,python CMD:pip install pyquery
pyquery支持三种类型的参数传入,分别是字符串(string),网址(url=‘www.baidu.com’),文件(filename=’.*.html’),举个例子:

from pyquery import PyQuery as pq
doc = pq(url='www.baidu.com)

细心的你在这里已经发现了问题:为啥传了一个网址进去,这怎么用。其实,pyquery自带了获取html的功能,它相当于:

doc = pq(requests.get('www.baidu.com).text)

2.基本用法

复习一下CSS选择器的规则。

lis = '''<div id="container"><div class="hd"><a href="https://movie.douban.com/subject/1291875/" class=""><span class="title">阳光灿烂的日子</span><span class="other">&nbsp;/&nbsp;In the Heat of the Sun</span></a></div><div class="bd"><p class="">导演: 姜文 Wen Jiang&nbsp;&nbsp;&nbsp;主演: 夏雨 Yu Xia / 宁静 Jing Ning / 陶虹 Hong Tao<br>1994&nbsp;/&nbsp;中国大陆 中国香港&nbsp;/&nbsp;剧情 爱情</p></div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(lis)
print(doc('#container .hd a span.title).text())
>>>阳光灿烂的日子

获取属性:调用attr方法(a.attr('href))或(a.attr.href);获取文本:text();获取html:html()

3.查找节点

(1)子节点和子孙节点

查找子节点,需要用到find()方法,会将符合条件的所有节点全部提取出来。如果只查找子节点,调用children()方法就即可。

(2)父节点和祖父节点

我们可以用parent()来获取某个节点的父节点,parent()获取祖先节点,可以传入参数筛选。

items = lis('span.title').parents('a')

(3)兄弟节点

获取兄弟节点可以用siblings()方法

4.文件类型

如期而至,让我们来看看pyquery的文件类型是什么。

print(type(doc))
<class 'pyquery.pyquery.PyQuery'>

如果获取的是单个节点,可以直接输出,也可以转化为字符串输出。
让我们来看看下面这种情况:

print(type(items))
<class 'generator'> #generator意思是"发生器",这个时候就需要历了。使用之前需要先用items()格式化。
for item in items.items()print(item)

!!!重点在这里,pyquery返回的多个节点需要用遍历处理。

5.节点处理

下面列举几种pyquery常用的节点处理的方法。

(1)addClass( ) 和removeClass( )

lis='''<div class="hd"><a href="https://movie.douban.com/subject/1291875/" class=""><span class="title">阳光灿烂的日子</span><span class="other">&nbsp;/&nbsp;In the Heat of the Sun</span></a></div>'''
from pyquery import PyQuery as pq
doc = pq(lis)
print(doc('.hd').removeClass('hd').addClass('hahah'))

(2)attr( )和text( )

print(doc('a').attr('name','link'))
print9doc('a').text('changed items)

(3)remove( )

比如提取标签里面“阳光灿烂的日子”

item = lis('a')
item.find('.other').remove()
print(item)

6.好了,pyquery的用法到这里也介绍完了

总结一下,功能强大,写法简洁。愿你解析半天,归来还是pq。

#Title1
##line2
###line3 >muname
<‘alert(‘hello world’);’ >
‘’’
<print(‘hello world’)>
‘’’
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tvW7TjBx-1585707653825)(C:\Users\tingy\Desktop\节点树.jpg)]

写在最后

从2020/03/31 15:20开始,到04/01 09:59,这一篇文章已经算是圆满了。再次感谢我妈和我的芬芬儿昨天晚上帮我洗碗,我才能够比较顺利的,时效的完成这篇梳理。

引用

[1]崔庆才,Python3网络开发与实践,[M],2018.4,人民邮电出版社。
[2]URL:https://docs.python.org/zh-cn/3.7/ 点击阅读python官方文档。
[3]python3 lxml标准库点击阅读lxml文档。
[4]沈承放,莫达隆,beautifulsoup库在网络爬虫中的使用技巧及应用,[J],2019.3,2019(28)点击阅读paper。
[5]风变编程——BeautifulSoup实践。

浅谈解析库XPath,bs4和pyquery相关推荐

  1. 解析库 xpath, beautifu soup , pyquery

    1.Xpath 节点,属性值获取都是列表 基本使用 from lxml import etree text = '<li>abc刘嘉强</li>' html = etree.H ...

  2. python数学库的使用方法_浅谈numpy库的常用基本操作方法

    NumPy数组的维数称为秩(rank),一维数组的秩为1,二维数组的秩为2,以此类推.在NumPy中,每一个线性的数组称为是一个轴(axes),秩其实是描述轴的数量.比如说,二维数组相当于是一个一维数 ...

  3. Python网络解析库Xpath,妈妈再也不会担心我不会解析了

    本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 极客导航 即可关注,每个工作日都有文章更新. 一.概况 前两篇我们把网络库Requests大概的用法学了一遍,把网站上的每页数据请求下 ...

  4. 爬虫(2)-解析库xpath和beautifulsoup爬取猫眼电影排行榜前100部电影

    解析库爬取猫眼电影前100部电影 认为有用的话请点赞,码字不易,谢谢. 其他爬虫实战请查看:https://blog.csdn.net/qq_42754919/category_10354544.ht ...

  5. python中bs4_浅谈Python中的bs4基础

    安装 在命令提示符框中直接输入pip install beautifulsoup4 介绍 beautifulsoup是python的一个第三方库,和xpath一样,都是用来解析html数据的. 引入 ...

  6. 爬虫解析库xpath

    # xpath简介 XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言.用于在 XML 文档中通过元素和属性进行导航. XPath基于XM ...

  7. 《崔庆才Python3网络爬虫开发实战教程》学习笔记(4):解析库Xpath的使用方法总结

    本篇博文是自己在学习崔庆才的<Python3网络爬虫开发实战教程>的学习笔记系列,如果你也要这套视频教程的话,关注我公众号[小众技术],关注后回复[PYTHON],无套路免费送你一个学习大 ...

  8. 六、爬虫中重要的解析库xpath和BeautifulSoup

    @Author:Runsen BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库,它的使用方式相对于正则来说更加的简单方便,常常能够节省我们大量的时间. 文章目录 ...

  9. python的openpyxl模块合并单元格,浅谈openpyxl库,遇到批量合并单元格的问题

    我就废话不多说了,大家还是直接看代码吧~ from openpyxl import Workbook from openpyxl import load_workbook from openpyxl. ...

最新文章

  1. ORA-00913错误:PL/SQL: ORA-00913: too many values
  2. eclipse中使用svn提交,更新代码。
  3. discuz!x2.5登录管理面板
  4. PHP操作Redis步骤详解
  5. 使用 Boost.MPI 的 reduce() 计算最小值的示例
  6. [剑指offer]面试题第[58-2]题[JAVA][左旋转字符串][拼接]
  7. wpe使用方法(详细)(--新加秒10图)(10号继续可用)
  8. 啥是前端开发工程师必会的5种网页布局方法?
  9. 论文分享Why Do Adversarial Attacks Transfer? Explaining Transferability of Evasion and Poisoning Attacks
  10. bzoj3384[Usaco2004 Nov]Apple Catching 接苹果*bzoj1750[Usaco2005 qua]Apple Catching*
  11. 360怎样修改wifi服务器,360路由器怎么重新设置? | 192路由网
  12. 女超人、女强人……究竟是谁在以“女”设限?
  13. 汽车门把手的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  14. Face Super-Resolution Guided by 3D Facial Priors(ECCV2020)论文解读
  15. 使用idb操作IndexedDB
  16. 小鼠肺内皮细胞 (MPEC)
  17. git基础配置/SSH
  18. AcWing 1309. 车的放置 (加法原理、乘法原理、组合数排列数的求法、乘法逆元)
  19. python编程入门到实践学习笔记——外星人入侵游戏pygame(二 外星人)
  20. ExtJS基础知识总结:常用控件使用方式(一)

热门文章

  1. 电商商家必看!海外抖音TikTok选品教程大放送
  2. centos7:在linux世界里,一切皆文件
  3. 戴尔linux改win7教程视频,戴尔笔记本win10改win7系统BIOS设置详细教程
  4. 数据库新技术前沿总结
  5. 三维vr全景摄影展示满足产品720立体浏览
  6. 中职计算机专业英语说课稿,中职英语说课稿范文
  7. 2021-10-08 vue.js实现抖音很火八卦时间数字罗盘屏保壁纸
  8. 【?】【9908】守望者的逃离
  9. 使用 Python 进行数据预处理的标准化
  10. 计算机英语教学设计反思,小学五年级英语教学设计与反思