如何从HTML或XML文件中提取数据的Python爬虫库Beautiful Soup概述

描述

Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库,简单来说,它能将HTML的标签文件解析成树形结构,然后方便地获取到指定标签的对应属性。

通过Beautiful Soup库,我们可以将指定的class或id值作为参数,来直接获取到对应标签的相关数据,这样的处理方式简洁明了。

当前最新的 Beautiful Soup 版本为4.4.0,Beautiful Soup 3 当前已停止维护。

Beautiful Soup 4 可用于 Python2.7 和 Python3.0,本文示例使用的Python版本为2.7。

博主使用的是Mac系统,直接通过命令安装库:

sudo easy_install beautifulsoup4

安装完成后,尝试包含库运行:

from bs4 import BeautifulSoup

若没有报错,则说明库已正常安装完成。

开始

本文会通过这个网页http://reeoo.com来进行示例讲解,如下图所示

BeautifulSoup 对象初始化

将一段文档传入 BeautifulSoup 的构造方法,就能得到一个文档对象。如下代码所示,文档通过请求url获取:

#coding:utf-8from bs4 import BeautifulSoupimport urllib2url = 'http://reeoo.com'request = urllib2.Request(url)response = urllib2.urlopen(request, timeout=20)content = response.read()soup = BeautifulSoup(content, 'html.parser')

request 请求没有做异常处理,这里暂时先忽略。BeautifulSoup 构造方法的第二个参数为文档解析器,若不传入该参数,BeautifulSoup会自行选择最合适的解析器来解析文档,不过会有警告提示。

也可以通过文件句柄来初始化,可先将HTML的源码保存到本地同级目录 reo.html,然后将文件名作为参数:

soup = BeautifulSoup(open('reo.html'))

可以打印 soup,输出内容和HTML文本无二致,此时它为一个复杂的树形结构,每个节点都是Python对象。

Ps. 接下来示例代码中所用到的 soup 都为该soup。

Tag

Tag对象与HTML原生文档中的标签相同,可以直接通过对应名字获取

tag = soup.titleprint tag

打印结果:

Reeoo - web design inspiration and website gallerytitle></p> <p style="text-indent: 2em;"> Name</p> <p style="text-indent: 2em;"> 通过Tag对象的name属性,可以获取到标签的名称</p> <p style="text-indent: 2em;"> print tag.name# title</p> <p style="text-indent: 2em;"> Attributes</p> <p style="text-indent: 2em;"> 一个tag可能包含很多属性,如id、class等,操作tag属性的方式与字典相同。</p> <p style="text-indent: 2em;"> 例如网页中包含缩略图区域的标签 article</p> <p style="text-indent: 2em;"> ...<article class="box">    <div id="main">    <ul id="list">        <li id="sponsor"><div class="sponsor_tips">div>            <script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1696&serve=CVYD42T&placement=reeoocom" id="_carbonads_js">script>        li>...</p> <p style="text-indent: 2em;"> 获取它 class 属性的值</p> <p style="text-indent: 2em;"> tag = soup.articlec = tag['class']print c     # [u'box']</p> <p style="text-indent: 2em;"> 也可以直接通过 .attrs 获取所有的属性</p> <p style="text-indent: 2em;"> tag = soup.articleattrs = tag.attrsprint attrs# {u'class': [u'box']}</p> <p style="text-indent: 2em;"> ps. 因为class属于多值属性,所以它的值为数组。</p> <p style="text-indent: 2em;"> tag中的字符串</p> <p style="text-indent: 2em;"> 通过 string 方法获取标签中包含的字符串</p> <p style="text-indent: 2em;"> tag = soup.titles = tag.stringprint s# Reeoo - web design inspiration and website gallery</p> <p style="text-indent: 2em;"> 文档树的遍历</p> <p style="text-indent: 2em;"> 一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点。Beautiful Soup提供了许多操作和遍历子节点的属性。</p> <p style="text-indent: 2em;"> 子节点</p> <p style="text-indent: 2em;"> 通过Tag的 name 可以获取到对应标签,多次调用这个方法,可以获取到子节点中对应的标签。</p> <p style="text-indent: 2em;"> 如下图:</p> <p align="center"> <img src='http://file.elecfans.com/web1/M00/58/D1/pIYBAFtdH92ARGXJAADOROaCQP0585.jpg' alt='python' /></p> <p style="text-indent: 2em;"> 我们希望获取到 article 标签中的 li</p> <p style="text-indent: 2em;"> tag = soup.article.div.ul.liprint tag</p> <p style="text-indent: 2em;"> 打印结果:</p> <p style="text-indent: 2em;"> <li id="sponsor"><div class="sponsor_tips">div><script async="" id="_carbonads_js" src="//cdn.carbonads.com/carbon.js?zoneid=1696&serve=CVYD42T&placement=reeoocom" type="text/javascript">script>li></p> <p style="text-indent: 2em;"> 也可以把中间的一些节点省略,结果也一致</p> <p style="text-indent: 2em;"> tag = soup.article.li</p> <p style="text-indent: 2em;"> 通过 . 属性只能获取到第一个tag,若想获取到所有的 li 标签,可以通过 find_all() 方法</p> <p style="text-indent: 2em;"> ls = soup.article.div.ul.find_all('li')</p> <p style="text-indent: 2em;"> 获取到的是包含所有li标签的列表。</p> <p style="text-indent: 2em;"> tag的 .contents 属性可以将tag的子节点以列表的方式输出:</p> <p style="text-indent: 2em;"> tag = soup.article.div.ulcontents = tag.contents</p> <p style="text-indent: 2em;"> 打印 contents 可以看到列表中不仅包含了 li 标签内容,还包括了换行符 ' '过tag的 .children 生成器,可以对tag的子节点进行循环</p> <p style="text-indent: 2em;"> tag = soup.article.div.ulchildren = tag.childrenprint childrenfor child in children:    print child</p> <p style="text-indent: 2em;"> 可以看到 children 的类型为 .contents 和 .children 属性仅包含tag的直接子节点,若要遍历子节点的子节点,可以通过 .descendants 属性,方法与前两者类似,这里不列出来了。</p> <p style="text-indent: 2em;"> 父节点</p> <p style="text-indent: 2em;"> 通过 .parent 属性来获取某个元素的父节点,article 的 父节点为 body。</p> <p style="text-indent: 2em;"> tag = soup.articleprint tag.parent.name# body</p> <p style="text-indent: 2em;"> 或者通过 .parents 属性遍历所有的父辈节点。</p> <p style="text-indent: 2em;"> tag = soup.articlefor p in tag.parents:    print p.name</p> <p style="text-indent: 2em;"> 兄弟节点</p> <p style="text-indent: 2em;"> .next_sibling 和 .previous_sibling 属性用来插叙兄弟节点,使用方式与其他的节点类似。</p> <p style="text-indent: 2em;"> 文档树的搜索</p> <p style="text-indent: 2em;"> 对树形结构的文档进行特定的搜索是爬虫抓取过程中最常用的操作。</p> <p style="text-indent: 2em;"> find_all()</p> <p style="text-indent: 2em;"> find_all(name , attrs , recursive , string , ** kwargs)</p> <p style="text-indent: 2em;"> name 参数</p> <p style="text-indent: 2em;"> 查找所有名字为 name 的tag</p> <p style="text-indent: 2em;"> soup.find_all('title')# [<title>Reeoo - web design inspiration and website gallerytitle>]soup.find_all('footer')# [<footer id="footer"> <div class="box"> <p> ... div> footer>]</p> <p style="text-indent: 2em;"> keyword 参数</p> <p style="text-indent: 2em;"> 如果指定参数的名字不是内置的参数名(name , attrs , recursive , string),则将该参数当成tag的属性进行搜索,不指定tag的话则默认为对所有tag进行搜索。</p> <p style="text-indent: 2em;"> 如,搜索所有 id 值为 footer 的标签</p> <p style="text-indent: 2em;"> soup.find_all(id='footer')# [<footer id="footer"> <div class="box"> <p> ... div> footer>]</p> <p style="text-indent: 2em;"> 加上标签的参数</p> <p style="text-indent: 2em;"> soup.find_all('footer', id='footer')# [ "footer"> </p> <p style="text-indent: 2em;"> class="box"> <p> ... </div> </footer>]# 没有id值为'footer'的div标签,所以结果返回为空soup.find_all('div', id='footer')# []</p> <p style="text-indent: 2em;"> 获取所有缩略图的 div 标签,缩略图用 class 为 thumb 标记</p> <p style="text-indent: 2em;"> soup.find_all('div', class_='thumb')</p> <p style="text-indent: 2em;"> 这里需要注意一点,因为 class 为Python的保留关键字,所以作为参数时加上了下划线,为“class_”。</p> <p style="text-indent: 2em;"> 指定名字的属性参数值可以包括:字符串、正则表达式、列表、True/False。</p> <p style="text-indent: 2em;"> True/False</p> <p style="text-indent: 2em;"> 是否存在指定的属性。</p> <p style="text-indent: 2em;"> 搜索所有带有 target 属性的标签</p> <p style="text-indent: 2em;"> soup.find_all(target=True)</p> <p style="text-indent: 2em;"> 搜索所有不带 target 属性的标签(仔细观察会发现,搜索结果还是会有带 target 的标签,那是不带 target 标签的子标签,这里需要注意一下。)</p> <p style="text-indent: 2em;"> soup.find_all(target=False)</p> <p style="text-indent: 2em;"> 可以指定多个参数作为过滤条件,例如页面缩略图部分的标签如下所示:</p> <p style="text-indent: 2em;"> ...<li>    <div class="thumb">        <a href="http://reeoo.com/aim-creative-studios">![AIM Creative Studios](http://upload-images.jianshu.io/upload_images/1346917-f6281ffe1a8f0b18.gif?imageMogr2/auto-orient/strip)a>    div>    <div class="title">        <a href="http://reeoo.com/aim-creative-studios">AIM Creative Studiosa>    div>li>...</p> <p style="text-indent: 2em;"> 搜索 src 属性中包含 reeoo 字符串,并且 class 为 lazy 的标签:</p> <p style="text-indent: 2em;"> soup.find_all(src=re.compile("reeoo.com"), class_='lazy')</p> <p style="text-indent: 2em;"> 搜索结果即为所有的缩略图 img 标签。</p> <p style="text-indent: 2em;"> 有些属性不能作为参数使用,如 data-**** 属性。在上面的例子中,data-original 不能作为参数使用,运行起来会报错,SyntaxError: keyword can't be an expression*。</p> <p style="text-indent: 2em;"> attrs 参数</p> <p style="text-indent: 2em;"> 定义一个字典参数来搜索对应属性的tag,一定程度上能解决上面提到的不能将某些属性作为参数的问题。</p> <p style="text-indent: 2em;"> 例如,搜索包含 data-original 属性的标签</p> <p style="text-indent: 2em;"> print soup.find_all(attrs={'data-original': True})</p> <p style="text-indent: 2em;"> 搜索 data-original 属性中包含 reeoo.com 字符串的标签</p> <p style="text-indent: 2em;"> soup.find_all(attrs={'data-original': re.compile("reeoo.com")})</p> <p style="text-indent: 2em;"> 搜索 data-original 属性为指定值的标签</p> <p style="text-indent: 2em;"> soup.find_all(attrs={'data-original': 'http://media.reeoo.com/Bersi Serlini Franciacorta.png!page'})</p> <p style="text-indent: 2em;"> string 参数</p> <p style="text-indent: 2em;"> 和 name 参数类似,针对文档中的字符串内容。</p> <p style="text-indent: 2em;"> 搜索包含 Reeoo 字符串的标签:</p> <p style="text-indent: 2em;"> soup.find_all(string=re.compile("Reeoo"))</p> <p style="text-indent: 2em;"> 打印搜索结果可看到包含3个元素,分别是对应标签里的内容,具体见下图所示</p> <p align="center"> </p> <p align="center"> </p> <p align="center"> </p> <p style="text-indent: 2em;"> limit 参数</p> <p style="text-indent: 2em;"> find_all() 返回的是整个文档的搜索结果,如果文档内容较多则搜索过程耗时过长,加上 limit 限制,当结果到达 limit 值时停止搜索并返回结果。</p> <p style="text-indent: 2em;"> 搜索 class 为 thumb 的 div 标签,只搜索3个</p> <p style="text-indent: 2em;"> soup.find_all('div', class_='thumb', limit=3)</p> <p style="text-indent: 2em;"> 打印结果为一个包含3个元素的列表,实际满足结果的标签在文档里不止3个。</p> <p style="text-indent: 2em;"> recursive 参数</p> <p style="text-indent: 2em;"> find_all() 会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False。</p> <p style="text-indent: 2em;"> find()</p> <p style="text-indent: 2em;"> find(name , attrs , recursive , string , ** kwargs)</p> <p style="text-indent: 2em;"> find() 方法和 find_all() 方法的参数使用基本一致,只是 find() 的搜索方法只会返回第一个满足要求的结果,等价于 find_all() 方法并将limit设置为1。</p> <p style="text-indent: 2em;"> soup.find_all('div', class_='thumb', limit=1)soup.find('div', class_='thumb')</p> <p style="text-indent: 2em;"> 搜索结果一致,唯一的区别是 find_all() 返回的是一个数组,find() 返回的是一个元素。</p> <p style="text-indent: 2em;"> 当没有搜索到满足条件的标签时,find() 返回 None, 而 find_all() 返回一个空的列表。</p> <p style="text-indent: 2em;"> CSS选择器</p> <p style="text-indent: 2em;"> Tag 或 BeautifulSoup 对象通过 select() 方法中传入字符串参数, 即可使用CSS选择器的语法找到tag。</p> <p style="text-indent: 2em;"> 语义和CSS一致,搜索 article 标签下的 ul 标签中的 li 标签</p> <p style="text-indent: 2em;"> print soup.select('article ul li')</p> <p style="text-indent: 2em;"> 通过类名查找,两行代码的结果一致,搜索 class 为 thumb 的标签</p> <p style="text-indent: 2em;"> soup.select('.thumb')soup.select('[class~=thumb]')</p> <p style="text-indent: 2em;"> 通过id查找,搜索 id 为 sponsor 的标签</p> <p style="text-indent: 2em;"> soup.select('#sponsor')</p> <p style="text-indent: 2em;"> 通过是否存在某个属性来查找,搜索具有 id 属性的 li 标签</p> <p style="text-indent: 2em;"> soup.select('li[id]')</p> <p style="text-indent: 2em;"> 通过属性的值来查找查找,搜索 id 为 sponsor 的 li 标签</p> <p style="text-indent: 2em;"> soup.select('li[id="sponsor"]')</p> <p style="text-indent: 2em;"> 其他</p> <p style="text-indent: 2em;"> 其他的搜索方法还有:</p> <p style="text-indent: 2em;"> find_parents() 和 find_parent()</p> <p style="text-indent: 2em;"> find_next_siblings() 和 find_next_sibling()</p> <p style="text-indent: 2em;"> find_previous_siblings() 和 find_previous_sibling()</p> <p style="text-indent: 2em;"> …</p> <p style="text-indent: 2em;"> 参数的作用和 find_all()、find() 差别不大,这里就不再列举使用方式了。这两个方法基本已经能满足绝大部分的查询需求。</p> <p style="text-indent: 2em;"> 还有一些方法涉及文档树的修改。对于爬虫来说大部分工作只是检索页面的信息,很少需要对页面源码做改动,所以这部分的内容也不再列举。</p> <!-- copy 原来页面的推送 --> <script type="application/ld+json"> { "@context": "https://zhanzhang.baidu.com/contexts/cambrian.jsonld", "@id": "https://m.elecfans.com/article/718479.html", "title": "如何从HTML或XML文件中提取数据的P", "images": [ "http://file.elecfans.com/web1/M00/58/D1/pIYBAFtdH92ARGXJAADOROaCQP0585.jpg" ], "description": "Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库,简单来说,它能将HTML的标签文件解析成树形结构,然后方便地获取到指定标签的对应属性。", "pubDate": "2018-07-29T09:56:24" } </script> <!-- end copy 原来页面的推送 --> </div> <!-- <a href="javascript:" target="_blank"></a> --> <!-- <a href="https://www.elecfans.com/app/download.html" class="open_app_arc baidu_click_tongji2 inAppHide" target="_blank">打开APP阅读更多精彩内容</a> --> <span class="open_app_arc baidu_click_tongji2 downAppBtn inAppHide">打开APP阅读更多精彩内容</span> <div class="see_more_arc hide"> <div class="arrow_more show_more"> <i></i> <i></i> </div> <button class="read_more">点击阅读全文</button> </div> </div> </div> <!--声明-无论是否原创都显示此声明--> <div class="statement"> 声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 <a class="complaint handleJumpBy" href="/about/tousu.html" target="_self">举报投诉</a> </div> <!--评论--> <div class="arc_comment comment"> </div> <!--查看电子发烧友网--> <div class="openx-hero inAppHide" style="text-align: center;"> <div class="advertWrap"> <a href="" target="_blank"> <img src=""> </a> </div> </div> <div class="rela_article"> <div class="rela_article_title flex"> <ul class="tab_lis flex"> <li><span>相关推荐</span></li> <li><a href="/tags/XML.html" target="_self" class="handleJumpBy advertTagId" data-id="3697">XML</a></li><li><a href="/tags/HTML.html" target="_self" class="handleJumpBy advertTagId" data-id="11462">HTML</a></li><li><a href="/tags/python.html" target="_self" class="handleJumpBy advertTagId" data-id="42127">python</a></li> </ul> </div> <ul class="rela_article_content"> <li > <a href="https://bbs.elecfans.com/jishu_1583155_1_1.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct"><b class='flag-m-1'>Python</b><b class='flag-m-1'>数据</b><b class='flag-m-1'>爬虫</b>学习内容</div> <div class="time_and_hot flex"> <span>2018-05-09</span> <span>0</span> </div> </a> </li><li > <a href="https://bbs.elecfans.com/jishu_1583549_1_1.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct"><b class='flag-m-1'>Python</b><b class='flag-m-1'>爬虫</b>与Web开发<b class='flag-m-1'>库</b>盘点</div> <div class="time_and_hot flex"> <span>2018-05-10</span> <span>0</span> </div> </a> </li><li > <a href="https://bbs.elecfans.com/jishu_1625699_1_1.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct">【NanoPi K1 Plus试用体验】<b class='flag-m-1'>python</b><b class='flag-m-1'>爬虫</b></div> <div class="time_and_hot flex"> <span>2018-08-03</span> <span>0</span> </div> </a> </li><li > <a href="https://bbs.elecfans.com/jishu_1710792_1_1.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct"><b class='flag-m-1'>Python</b> <b class='flag-m-1'>爬虫</b>:8 个常用的<b class='flag-m-1'>爬虫</b>技巧总结!</div> <div class="time_and_hot flex"> <span>2019-01-02</span> <span>0</span> </div> </a> </li><li > <a href="https://bbs.elecfans.com/jishu_1843448_1_1.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct">【建议收藏】<b class='flag-m-1'>Python</b><b class='flag-m-1'>库</b>大全</div> <div class="time_and_hot flex"> <span>2019-09-06</span> <span>0</span> </div> </a> </li><li > <a href="https://bbs.elecfans.com/jishu_2269071_1_1.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct"><b class='flag-m-1'>python</b>网络<b class='flag-m-1'>爬虫</b><b class='flag-m-1'>概述</b></div> <div class="time_and_hot flex"> <span>2022-03-21</span> <span>0</span> </div> </a> </li><li > <a href="https://bbs.elecfans.com/jishu_2355559_1_1.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct">如何<b class='flag-m-1'>从</b>LittleFS<b class='flag-m-1'>中提取</b>自定义字体<b class='flag-m-1'>文件</b>?</div> <div class="time_and_hot flex"> <span>2023-05-11</span> <span>0</span> </div> </a> </li><li > <a href="https://www.elecfans.com/soft/6/2016/20160327408906.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct">JAVA教程之<b class='flag-m-1'>从</b>压缩包<b class='flag-m-1'>中提取</b><b class='flag-m-1'>文件</b></div> <div class="time_and_hot flex"> <span>2016-04-11</span> <span>442</span> </div> </a> </li><li > <a href="https://www.elecfans.com/d/1414733.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct"><b class='flag-m-1'>Python</b><b class='flag-m-1'>爬虫</b>之<b class='flag-m-1'>Beautiful</b> <b class='flag-m-1'>Soup</b>模块</div> <div class="time_and_hot flex"> <span>2020-12-10</span> <span>401</span> </div> </a> </li><li > <a href="https://www.elecfans.com/d/1575401.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct"><b class='flag-m-1'>Python</b>中BeatifulSoap解析<b class='flag-m-1'>HTML</b>的三个实用小技巧详解</div> <div class="time_and_hot flex"> <span>2021-04-15</span> <span>2033</span> </div> </a> </li><li > <a href="https://www.elecfans.com/d/1791969.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct">MySQL端口可以<b class='flag-m-1'>从</b>MySQL<b class='flag-m-1'>数据库</b>中存储和检索<b class='flag-m-1'>数据</b></div> <div class="time_and_hot flex"> <span>2022-02-15</span> <span>1645</span> </div> </a> </li><li > <a href="https://www.elecfans.com/d/1999768.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct">如何使用OpenCV和<b class='flag-m-1'>Python</b><b class='flag-m-1'>从</b>图像<b class='flag-m-1'>中提取</b>感兴趣区域</div> <div class="time_and_hot flex"> <span>2023-02-07</span> <span>1769</span> </div> </a> </li><li > <a href="https://www.elecfans.com/d/2147757.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct">OST<b class='flag-m-1'>中提取</b>邮箱<b class='flag-m-1'>数据</b>和重置丢失的WindowsServer 密码的工具</div> <div class="time_and_hot flex"> <span>2023-06-24</span> <span>1160</span> </div> </a> </li><li > <a href="https://www.elecfans.com/d/2282574.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct">Newspaper:用于<b class='flag-m-1'>提取</b>和整理文章的<b class='flag-m-1'>python</b><b class='flag-m-1'>库</b></div> <div class="time_and_hot flex"> <span>2023-10-30</span> <span>706</span> </div> </a> </li><li > <a href="https://www.elecfans.com/d/3649128.html" target="_self" class="handleJumpBy"> <div class="rela_article_ct">常见的<b class='flag-m-1'>数据</b>采集工具的介绍</div> <div class="time_and_hot flex"> <span>2024-07-01</span> <span>680</span> </div> </a> </li> </ul> </div> <div class="go_elecfans ad-demo inAppHide"></div> <!-- 全部评论 --> <div class="all-comment comment"> <div class="all-comment-content"> <div class="all-com-close flex"> <p class="ph">全部<i>0</i>条评论</p> <span class="close_com"></span> <!-- <span class="edit_com">写评论</span> --> </div> <div class="all_words comment_content" id="all_words"> <div id="scroller"></div> </div> <div class="all_no_comment" class="hide"> <img src="https://staticm.elecfans.com/images/newdetail/all_no_bg.png" alt=""> <p>快来发表一下你的评论吧 !</p> </div> </div> <div class="ft"> <input type="text" placeholder="发评论" maxlength="10000"> <button>发送</button> </div> </div> <input type="hidden" id="cover_desc" value=" Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库,简单来说,它能将HTML的标签文件解析成树形结构,然后方便地获取到指定标签的对应属性。 通过Beautiful Soup库,我们可以将指定的class或id值作为参数,来直接获取到对应标签的相关数据,这样的处理方式简洁明了。 当前最新的 Beautiful Soup 版本为4.4.0,Beautiful So"> <input type="hidden" id="current_url" value="https://m.elecfans.com/article/718479.html"> <input type="hidden" id="title" value="如何从HTML或XML文件中提取数据的Python爬虫库Beautiful Soup概述"> <input type="hidden" id="pc_domain" value="https://www.elecfans.com"> <input type="hidden" id="aid" value="718479"> <input type="hidden" id="pid" value=""> <!-- 文章作者id --> <input type="hidden" id="column_uid" value="2737481"> <!-- 企业号文章id --> <input type="hidden" id="evip_article_id" value=""> <!-- 是企业号文章 store_flag =15 --> <input type="hidden" id="store_flag" value="0"> <input type="hidden" id="evip_type" value="0"> <!-- 是企业号文章 store_flag =15 --> <input type="hidden" id="evip_id" value="0"> <!--打开APP底部悬浮按钮--> <!-- <div class="open_app_btn">打开APP</div> --> <footer class="art_footer flex"> <input type="text" placeholder="发评论" maxlength="10000" id="commentTxt"> <div class="flex"> <span class="ft_comment" data-com="发评论"> <i class="sups"></i> </span> <span class="ft_give_up "> <!-- --> </span> <span class="ft_star "> <!-- --> </span> <span class="ft_share btn-createCover"></span> </div> </footer> <div class="login-reg-fixed inAppHide" data-uid="0"> <a href="/login.html" class="login-reg-btn"> 登录/注册 </a> </div> <!--二维码--> <img src="" alt="" id="qrious" style="display: none;"> <!--老的底部 隐藏 --> <div class="new-footer inAppHide"> <div class="flex-center"><a href="https://www.elecfans.com/app/download.html" target="_blank">下载APP</a></div> <div class="flex-center"> <a href="/login.html" class="login-reg-btn"> 登录注册 </a> <span class="line">|</span><a href="https://m.elecfans.com/about/tousu.html">投诉反馈</a><span class="line">|</span><a href="https://author.baidu.com/home/1563378682824805?from=dusite_artdetailh5">电子发烧友网</a> </div> <div class="flex-center">© 2021 elecfans.com</div> <div class="flex-center"><a href="https://beian.miit.gov.cn/">湘ICP备2023018690号</a></div> <div><input type="hidden" value="0" name="arc_relate_vid"></div> </div> </div> <!--微信分享图片地址--> <input type="hidden" id="shareWxImg" value="http://file.elecfans.com/web1/M00/58/D1/pIYBAFtdH92ARGXJAADOROaCQP0585.jpg"> <!--微信分享图片地址--> <script> /** * 判断是否微信浏览器 * @return {Boolean} [description] */ function is_weixin() { var ua = navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) == "micromessenger") { return true; } else { return false; } } $(function () { $(window).scroll(function (e) { var window_w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var window_h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; if (document.body.scrollTop + document.documentElement.scrollTop > window_h * 2) { $('.go_top').show(); } else { $('.go_top').hide(); } }); $('.go_top').on('click', function () { document.body.scrollTop = 0; document.documentElement.scrollTop = 0; return false; }); // 添加广告链接的Google Analytics事件跟踪 $('a').on('click', function () { var href = $(this).attr('href'); if (href) { var bannerArr = href.match(/__bannerid=(\d+)__/); var zoneidArr = href.match(/__zoneid=(\d+)__/); if ((bannerArr instanceof Array) && bannerArr.length == 2) { var bannerid = bannerArr[1]; var zoneid = zoneidArr[1]; ga('send', 'event', 'mElecfansAd', 'click', 'zoneid:' + zoneid + ',bannerid: ' + bannerid, 1); gtag('event', 'mElecfansAd', { 'zoneid': zoneid, 'bannerid': 'bannerid', 'describe': 'click' }); } } }); // 微信浏览器底部显示关注微信 /* if (is_weixin()) { $('#foot-fixed').hide(); $('#foot-fixed-wx').show(); }*/ $('#foot-img-wx-small').click(function () { $('#body-wx-big img').toggle(); }); }); </script> <!-- 是否完善资料代码 s --> <div class="perfect_infomation_tip"> <span class="no_tip_day3">×</span> <div class="perfect_infomation_tip_box go_perfect_btn"> <span class="tip_jifen_text">20</span> <div> <img class="tip_jifen" src="https://staticm.elecfans.com/images/tip_jifen.png"> </div> <div> 完善资料,<br>赚取积分 </div> </div> </div> <!-- 是否完善资料代码 e --> <script src="https://staticm.elecfans.com/weixinPrize/js/layer_mobile/layer.js"></script> <script src="https://staticm.elecfans.com/organizing/js/organizing.js?20230825" type="text/javascript" ></script> <script src="https://staticm.elecfans.com/hqAdvert.js?v2" type="text/javascript" ></script> <script src="https://staticm.elecfans.com/xgPlayer.js" type="text/javascript" ></script> <script> $(function(){ var scrollTimer $(window).on("scroll",function(){ //滚动的时候悬浮缩回去 否则正常展示 $(".perfect_infomation_tip_box").css("right","0px") clearTimeout(scrollTimer); scrollTimer=setTimeout(function(){ $(".perfect_infomation_tip_box").css("right"," -70px"); },300) }) // 用户下载附件判断登录 $("a[data-annex]").click(function(){ if($("#uid").attr("data-uid")== "0" || !$("#uid").attr("data-uid")){ window.location.href="/login.html" }else{ var down_id= $(this).attr("data-annex"); var down_href= $('#'+down_id).val(); window.open(down_href); } return false }) /* //判断当天是否弹出手机验证如果弹出这 if(typeof isVerification_new === "function"){ if(window.localStorage.getItem("m_verification")!==newDate_current()){ //弹出是否手机验证 //弹出是否手机验证 isVerification_new(function(){ //完成手机号验证 后判断是否完善资料 isPerfectInfo_phone($) }) } }*/ }); (function () { //百度推广 var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); //add sunjinliang 2021.1.11 copy 原来的统计 var user_uname = $('input[name="column-type-name"]').val(); //发烧友增加百度统计自定义变量统计单一用户数据访问量 var _hmt = _hmt || []; if (_hmt && user_uname == '发烧友学院') { _hmt.push(['_setCustomVar', 1, 'ChannelID', '发烧友学院', 3]); } var google_title = user_uname; ga('send', { hitType: 'pageview', title: google_title, dimension0: 'Mobile' }); gtag('event', 'pageview', { 'title': google_title, 'dimension0': 'Mobile', 'describe': 'pageview' }); $(".baidu_click_tongji1").click(function(){ sendGA("头部") }) $(".baidu_click_tongji2").click(function(){ sendGA("中部") }) $(".baidu_click_tongji3").click(function(){ sendGA("尾部") }) function sendGA(content){ //向百度发送数据 if(typeof(_hmt)!="undefined"){ //时间分类===_trackEvent 详情专题页面==zt_detail 点击事件==='click' 哪一个部分点击(content)==== 头部中部尾部 _hmt.push(['_trackEvent', "zt_detail", 'click', content]); } } })(); </script> <script src="https://staticm.elecfans.com/artilePartjs.js?v=20230803160700" type="text/javascript" ></script> </body> </html>