马哥Linux运维
2018-07-29
25847
分享海报
描述
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='XML' /></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">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>459</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>504</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>2174</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>1772</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>1997</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>1390</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>916</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>1324</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>