0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Python中BeatifulSoap解析HTML的三个实用小技巧详解

jf_f8pIz0xS ? 来源:CSDN技术社区 ? 作者:LaoYuanPython ? 2021-04-15 13:51 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、BeautifulSoup简介

BeautifulSoup是Python爬虫应用解析Html的利器,是Python三方模块bs4中提供的进行HTML解析的类,可以认为是一个HTML解析工具箱,对HTML报文中的标签具有比较好的容错识别功能。lxml是一款html文本解析器,BeautifulSoup构建对象时需要指定HTML解析器,推荐使用lxml。

BeautifulSoup和lxml安装命令:

1pip install -i https://pypi.tuna.tsinghua.edu.cn/simple bs4

2pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lxml

加载BeautifulSoup:

1from bs4 import BeautifulSoup

BeatifulSoap解析HTML报文的常用功能:

通过BeautifulSoup对象可以访问标签对应的html元素、并进一步访问标签的名字、属性、html元素标签对中的内容。

案例:

1from bs4 import BeautifulSoup

2import urllib.request

3def getURLinf(url):

4header = {‘User-Agent’: ‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36’}

5req = urllib.request.Request(url=url,headers=header)

6resp = urllib.request.urlopen(req,timeout=5)

7html = resp.read().decode()

8soup = BeautifulSoup(html,‘lxml’)

9return (soup,req,resp)

10soup,req ,resp = getURLinf(r‘https://blog.csdn.net/LaoYuanPython/article/details/111303395’)

11print(soup.p)

12print(soup.link)

13print(soup.title)

14print(soup.link.attrs)

15print(soup.link[‘rel’])

通过标签的contents属性,可以访问其下嵌套的所有下级HTML元素,这些该标签下的子标签对应的HTML元素放到一个contents 指向的列表中。

如:print(soup.body.contents)

可以访问标签对应的父、子、兄弟及祖先标签信息;

使用strings属性迭代访问除标签外的所有内容;

可以使用find、find_all、find_parent、find_parents等系列方法查找满足特定条件的标签;

使用select通过css选择器定位特定标签。

具体的大家可以参考老猿博客的免费专栏《爬虫:https://blog.csdn.net/laoyuanpython/category_9103810.html》或付费专栏《Python爬虫入门:https://blog.csdn.net/laoyuanpython/category_10762553.html》的相关介绍。

二、一些解析技巧

在HTML解析时,如果通过简单的tag、或单个tag属性(如id、class)或文本一次搜索或select定位是最简单的,而有些情况需要使用组合方法才能处理。

2.1、通过标签的多个属性组合定位或查找

经常有些要定位的标签有很多,按单个属性查找也有很多,得使用多个属性查找。如:

1《div id=“article_content” class=“article_content clearfix”》

2。。.。。.

3《/div》

4《div id=“article_content” class=“article_view”》

5。。.。。.

6《/div》

7《div id=“article_view” class=“article_view”》

8。。.。。.

9《/div》

上面的html文本中有多个id为article_content的div标签,如果使用:

1》》》 text=“”“```html

2《div id=”article_content“ class=”article_content clearfix“》

3。。.。。.

4《/div》

5《div id=”article_content“ class=”article_view“》

6。。.。。.

7《/div》

8《div id=”article_view“ class=”article_view“》

9。。.。。.

10《/div》”“”

11》》》 s = BeautifulSoup(text,‘lxml’)

12》》》 s.select(‘div#article_content’)

13[《div class=“article_content clearfix” id=“article_content”》。。.。。.《/div》,

14《div class=“article_view” id=“article_content”》。。.。。.《/div》]

15》》》

就会返回两条记录。这时候就可以使用多标签属性定位的如下4种语句:

1》》》s.select(‘div#article_content[class=“article_content clearfix”]’)

2[《div class=“article_content clearfix” id=“article_content”》。。.。。.《/div》]

3》》》s.select(‘div[id=“article_content”][class=“article_content clearfix”]’)

4[《div class=“article_content clearfix” id=“article_content”》。。.。。.《/div》]

5》》》s.find_all(“div”,id=“article_content”,class_=‘article_content clearfix’)

6[《div class=“article_content clearfix” id=“article_content”》。。.。。.《/div》]

7》》》s.find_all(“div”,“#article_content”,class_=‘article_content clearfix’)

8[《div class=“article_content clearfix” id=“article_content”》。。.。。.《/div》]

以上四种方式是等价的,因为id可以用#来标记,class在查找时需要和Python关键字class区分,因此有上述不同方法,注意select的每个属性必须用中括号括起来,不同属性的中括号之间不能有空格,如果有空格表示的就不是查找同一标签的属性,空格后的属性表示前一个属性对应标签的子孙标签的属性。

2.2、利用tag标签关系定位内容

tag标签关系包括父子、兄弟、祖先等关系,有时要查找或定位的内容本身不是很好定位,但结合其他标签关系(主要是父子、祖先关系)则可以唯一确认。

案例:

这是CSDN的博文中关于博主个人信息的部分报文:

1《div class=“data-info d-flex item-tiling”》

2《dl class=“text-center” title=“1055”》

3《a href=“https://blog.csdn.net/LaoYuanPython” data-report-click=‘{“mod”:“1598321000_001”,“spm”:“1001.2101.3001.4310”}’ data-report-query=“t=1”》

4《dt》《span class=“count”》1055《/span》《/dt》

5《dd class=“font”》原创《/dd》

6《/a》

7《/dl》

8《dl class=“text-center” data-report-click=‘{“mod”:“1598321000_002”,“spm”:“1001.2101.3001.4311”}’ title=“22”》

9《a href=“https://blog.csdn.net/rank/writing_rank” target=“_blank”》

10《dt》《span class=“count”》22《/span》《/dt》

11《dd class=“font”》周排名《/dd》

12《/a》

13《/dl》

14《/div》

以上报文中,如果要取博主的原创文章数和周排名,原创文章数和博主周排名的tag标签完全相同,二者都在span标签内,标签的属性及值都相同,只是span标签的父标签dt标签的兄弟标签dd标签的string的中文内容才能区分。对于这种情况,首先要通过祖先标签《div class=“data-info d-flex item-tiling”》定位到祖先标签,再在祖先标签内通过中文字符串定位到要访问属性的兄弟标签的子标签,然后通过该子标签找到其父标签的父标签,再通过该父标签的dt子标签的span子标签访问具体取值。

示例代码如下:

1》》》 text=“”“

2《div class=”data-info d-flex item-tiling“》

3《dl class=”text-center“ title=”1055“》

4《a href=”https://blog.csdn.net/LaoYuanPython“ data-report-click=‘{”mod“:”1598321000_001“,”spm“:”1001.2101.3001.4310“}’ data-report-query=”t=1“》

5《dt》《span class=”count“》1055《/span》《/dt》

6《dd class=”font“》原创《/dd》

7《/a》

8《/dl》

9《dl class=”text-center“ data-report-click=‘{”mod“:”1598321000_002“,”spm“:”1001.2101.3001.4311“}’ title=”22“》

10《a href=”https://blog.csdn.net/rank/writing_rank“ target=”_blank“》

11《dt》《span class=”count“》22《/span》《/dt》

12《dd class=”font“》周排名《/dd》

13《/a》

14《/dl》

15《/div》”“”

16》》》 s = BeautifulSoup(text,‘lxml’)

17》》》 subSoup = s.select(‘[class=“data-info d-flex item-tiling”] [class=“font”]’)

18》》》 for item in subSoup:

19parent = item.parent

20if item.string==‘原创’:

21orignalNum = int(parent.select(‘.count’)[0].string)

22elif item.string==‘周排名’:

23weekRank = int(parent.select(‘.count’)[0].string)

24》》》 print(orignalNum,weekRank)

251055 22

26》》》

注意:上面的select使用的也是标签的属性来定位标签,并且两个中括号之间有空格,表明后一个要查找的标签在前一个属性对应标签的子孙标签范围内。

2.3、分析前去除程序代码避免干扰

在解析HTML报文时,绝大多数情况是需要分析有用的标签信息,但作为技术文章,大部分的博文中都有代码,这些代码可能会对分析进行干扰。如本文中的代码含有一些分析的HTML报文,如果获取本文的完整HTML内容,这些报文在非代码部分也会出现,此时要排除代码的影响,可以将代码先从分析内容中去除再来分析。

目前大多数技术平台的博文编辑器都支持对代码的标识,象markdown等编辑器代码的标签为code标检,如果有其他编辑器用不同标签的,只有确认了标签名,都可以按下面介绍的类似方式来处理。

处理步骤如下:

获取报文;

构建BeatifulSoap对象soup;

通过soup.code.extract()或soup.code.decompose()方式就从soup对象中去除了代码部分,decompose方法与extract方法的区别就是decompose直接删除对应对象数据而extract再删除时将删除对象单独返回。

关于这部分内容的案例可以参考《https://blog.csdn.net/LaoYuanPython/article/details/114729045 n行Python代码系列:四行程序分离HTML报文中的程序代码》的详细介绍。

三、小结

本文介绍了使用BeatifulSoap解析HTML报文的三个使用技巧,包括通过多属性组合查找或定位标签、通过结合多个标签关系来定位标签以及去除html报文中的代码标签来避免代码对解析的影响。

编辑:lyn

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • HTML
    +关注

    关注

    0

    文章

    280

    浏览量

    43021
  • python
    +关注

    关注

    56

    文章

    4831

    浏览量

    87380
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    DC/DC转换器选型的三个要点

    在上一篇《DC/DC 转换器电路设计与开发 — 类型与工作原理》,我们介绍了 DC/DC 转换器的类型以及降压型 DC/DC 转换器和升压型 DC/DC转换器的工作原理。本文将为大家分享 DC/DC 转换器选型的三个要点,以及电感器选型的计算方法。
    的头像 发表于 06-12 16:44 ?926次阅读
    DC/DC转换器选型的<b class='flag-5'>三个</b>要点

    半导体制造过程三个主要阶段

    前段工艺(Front-End)、中段工艺(Middle-End)和后段工艺(Back-End)是半导体制造过程三个主要阶段,它们在制造过程扮演着不同的角色。
    的头像 发表于 03-28 09:47 ?3023次阅读
    半导体制造过程<b class='flag-5'>中</b>的<b class='flag-5'>三个</b>主要阶段

    如何检测极管的三个

    可以用万用表来初步确定极管的好坏及类型 (NPN 型还是 PNP 型 ),并辨别出e(发射极)、b(基极)、c(集电极)三个电极。
    发表于 03-08 16:40

    如何区分场效应管mos管三个引脚

    场效应管mos管三个引脚怎么区分
    发表于 03-07 09:20 ?0次下载

    Linux系统中最重要的三个命令

    Linux剑客是Linux系统中最重要的三个命令,它们以其强大的功能和广泛的应用场景而闻名。这三个工具的组合使用几乎可以完美应对Shell的数据分析场景,因此被统称为Linux
    的头像 发表于 03-03 10:37 ?472次阅读

    使用DDS生成三个信号并在Vivado实现低通滤波器

    本文使用 DDS 生成三个信号,并在 Vivado 实现低通滤波器。低通滤波器将滤除相关信号。
    的头像 发表于 03-01 14:31 ?1827次阅读
    使用DDS生成<b class='flag-5'>三个</b>信号并在Vivado<b class='flag-5'>中</b>实现低通滤波器

    请问DLP4710 EVM-LC的RGB三个LED的参数是多少?

    DLP4710 EVM-LC的RGB三个LED 的参数是多少?用什么产品代替可以满足功率和亮度的要求
    发表于 02-26 07:50

    如何使用Python实现PID控制

    PID控制(比例-积分-微分控制)是一种常见的反馈控制算法,广泛应用于工业控制系统。在Python实现PID控制,我们可以遵循以下步骤: 1. 理解PID控制原理 PID控制器有三个
    的头像 发表于 11-14 09:09 ?1660次阅读

    Python解析:通过库实现代理请求与数据抓取

    Python,有多个库可以帮助你实现代理请求和数据抓取。这些库提供了丰富的功能和灵活的API,使得你可以轻松地发送HTTP请求、处理响应、解析HTML/XML/JSON数据,以及进
    的头像 发表于 10-24 07:54 ?503次阅读

    简述光刻工艺的三个主要步骤

    “ 光刻作为半导体的关键工艺,其中包括3大步骤的工艺:涂胶、曝光、显影。三个步骤有一异常,整个光刻工艺都需要返工处理,因此现场异常的处理显得尤为关键”
    的头像 发表于 10-22 13:52 ?2309次阅读

    自动发电控制系统具有三个基本功能

    自动发电控制系统(AGC)具有三个基本功能,这些功能在电力系统的运行和调度中发挥着重要作用。以下是这三个基本功能的详细解析
    的头像 发表于 10-03 15:05 ?1723次阅读

    机械振动的三个基本要素

    机械振动是物体或质点在其平衡位置附近进行的往复运动。在物理学,机械振动是一种非常普遍的现象,它涉及到许多不同的物理过程和应用。机械振动的三个基本要素是:振幅、周期和频率。 1. 振幅
    的头像 发表于 09-26 14:55 ?2807次阅读

    三个电流怎么判断NPN还是PNP

    在判断晶体管是NPN型还是PNP型时,主要依据是其内部半导体材料的排列方式以及电流在晶体管的流动方向。阐述如何根据三个电流(通常指的是发射极电流IE、基极电流IB和集电极电流IC)来判断NPN和PNP晶体管。
    的头像 发表于 09-14 15:44 ?4162次阅读

    基本理想电路元件的三个特征是什么

    基本理想电路元件是构成电路的基本单元,它们具有三个基本特征:电压-电流关系、能量转换和电路参数。以下是对这三个特征的分析: 电压-电流关系 理想电路元件的电压-电流关系是其最基本的特征之一。这种关系
    的头像 发表于 08-25 09:38 ?2464次阅读

    对称相电压的特点是哪三个方面

    相电压的特点。 一、对称相电压的基本概念 1.1 相电压的定义 相电压是指在电力系统,由三个相位组成的电压。这
    的头像 发表于 08-12 18:18 ?3292次阅读