14-5 解析网页Python程序设计基础教程(微课版第2版)_第1页
14-5 解析网页Python程序设计基础教程(微课版第2版)_第2页
14-5 解析网页Python程序设计基础教程(微课版第2版)_第3页
14-5 解析网页Python程序设计基础教程(微课版第2版)_第4页
14-5 解析网页Python程序设计基础教程(微课版第2版)_第5页
已阅读5页,还剩83页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

BeautifulSoup的使用解析网页CHAPTER14CONTENTS目

录01BeautifulSoup简介02BeautifulSoup四大对象03遍历文档树CONTENTS目

录04搜索文档树05CSS选择器解析网页爬取到一个网页数据进行解析获取数据内容解析网页BeautifulSoup

是一个HTML/XML的解析器解析HTML/XML数据提取HTML/XML数据解析网页BeautifulSoup简介简单、Python式的函数处理导航搜

索修改分析树解析网页BeautifulSoup是一个工具箱,通过解析文档为用户提供需要抓取的数据解析网页输入文档转换为Unicode编码输出文档转换为UTF-8编码BeautifulSoup解析网页使用BeautifulSoup4之前,需要安装bs4>pipinstallbs4解析网页APIhtml5lib解析器lxml的HTML解析器支持lxml的XML解析器Python标准库中的HTML解析器CSS选择器解析网页每个解析器的优缺点解析器用法优点缺点Python标准库BeautifulSoup(markup,"html.parser")Python标准库执行速度适中文档容错能力差lxml的HTML解析器BeautifulSoup(markup,"lxml")速度快文档容错能力强需要安装C语言库lxml的XML解析器BeautifulSoup(markup,"lxml-xml")BeautifulSoup(markup,"xml")速度快唯一支持XML的解析器需要安装C语言库html5libBeautifulSoup(markup,"html5lib")兼容性好以浏览器的方式解析文档生成HTML5格式的文档速度慢不依赖外部扩展解析网页如果需要快速解析网页,建议使用lxml解析器;如果使用的Python2.x是2.7.3之前的版本,或者使用的Python3.x是3.2.2之前的版本,则很有必要安装使用html5lib或lxml解析器,因为Python内建的HTML解析器不能很好地适应于这些老版本解析网页需要执行如下命令安装lxml解析器>pipinstalllxmlBeautifulSoup解析网页>>>html_doc="""<html><head><title>BigDataSoftware</title></head><pclass="title"><b>BigDataSoftware</b></p><pclass="bigdata">Therearethreefamousbigdatasoftwares;andtheirnamesare<ahref="/hadoop"class="software"id="link1">Hadoop</a>,<ahref="/spark"class="software"id="link2">Spark</a>and<ahref="/flink"class="software"id="link3">Flink</a>;andtheyarewidelyusedinrealapplications.</p><pclass="bigdata">...</p>"""【例】

下面给出一个BeautifulSoup解析网页的简单实例,实例代码如下解析网页>>>frombs4importBeautifulSoup>>>soup=BeautifulSoup(html_doc,"lxml")>>>content=soup.prettify()>>>print(content)<html><head><title>BigDataSoftware</title></head><body><pclass="title"><b>BigDataSoftware</b></p><pclass="bigdata">Therearethreefamousbigdatasoftwares;andtheirnamesare<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>and解析网页<aclass="software"href="/flink"id="link3">Flink</a>;andtheyarewidelyusedinrealapplications.</p><pclass="bigdata">...</p></body></html>解析网页soup=BeautifulSoup(html_doc,"lxml")使用Python标准库的解析器更

换如果要更换解析器soup=BeautifulSoup(html_doc,"html.parser")解析网页BeautifulSoup四大对象TagBeautifulSoupCommentNavigableString解析网页<title>BigDataSoftware</title><ahref="/hadoop"class="software"id="link1">Hadoop</a>Tag

是

HTML

中的一个个标签<title><a>解析网页>>>print(soup.a)<aclass="software"href="/hadoop"id="link1">Hadoop</a>>>>print(soup.title)<title>BigDataSoftware</title>执行如下代码解析网页>>>print()[document]>>>print(soup.p.attrs){'class':['title']}【例】Tag属性包括name和attrs,实例解析网页如果想要单独获取某个属性,比如要获取“class”属性的值>>>print(soup.p['class'])['title']还可以利用get方法获得属性的值,代码如下>>>print(soup.p.get('class'))['title']解析网页NavigableStringNavigableString对象用于操纵字符串。在网页解析时,已经得到了标签的内容以后,如果我们想获取标签内部的文字,则可以使用.string方法,其返回值就是一个NavigableString对象解析网页>>>print(soup.p.string)BigDataSoftware>>>print(type(soup.p.string))<class'bs4.element.NavigableString'>【例】NavigableString对象具体实例解析网页文档一个文档的全部内容Tag对象一个特殊的TagBeautifulSoup对象BeautifulSoup解析网页>>>print(type())<class'str'>>>>print()[document]>>>print(soup.attrs){}【例】分别获取类型、名称及属性BeautifulSoup解析网页CommentComment对象是一种特殊类型的NavigableString对象,输出的内容不包括注释符号解析网页【例】为了演示Comment对象,重新创建一个代码文件bs4_example.py01#bs4_example.py02html_doc="""03<html><head><title>TheDormouse'sstory</title></head>04<pclass="title"><b>TheDormouse'sstory</b></p>05<pclass="story">Onceuponatimetherewerethreelittlesisters;andtheirnameswere06<ahref="/elsie"class="sister"id="link1"><!--Elsie--></a>,07<ahref="/lacie"class="sister"id="link2">Lacie</a>and08<ahref="/tillie"class="sister"id="link3">Tillie</a>;解析网页【例】Comment

对象的具体操作实例09andtheylivedatthebottomofawell.</p>10<pclass="story">...</p>11"""12frombs4importBeautifulSoup13soup=BeautifulSoup(html_doc,"lxml")14print(soup.a)15print(soup.a.string)16print(type(soup.a.string))执行结果<aclass="sister"href="/elsie"id="link1"><!--Elsie--></a>Elsie<class'bs4.element.Comment'><!--Elsie-->“注释”解析网页BeautifulSoupBeautifulSoup通常把两者结合起来完成查找任务遍历文档树搜索文档树解析网页遍历文档树从根节点html标签开始遍历找到目标元素解析网页遍历文档树——直接子节点Tag对象的.contents属性可以将某个Tag的子节点以列表的方式输出,当然列表会允许用索引的方式来获取列表中的元素contents属性解析网页【例】遍历文档树直接子节点.contents

属性的具体操作实例>>>html_doc="""<html><head><title>BigDataSoftware</title></head><pclass="title"><b>BigDataSoftware</b></p><pclass="bigdata">Therearethreefamousbigdatasoftwares;andtheirnamesare<ahref="/hadoop"class="software"id="link1">Hadoop</a>,<ahref="/spark"class="software"id="link2">Spark</a>and<ahref="/flink"class="software"id="link3">Flink</a>;andtheyarewidelyusedinrealapplications.</p><pclass="bigdata">...</p>"""解析网页【例】遍历文档树直接子节点.contents

属性的具体操作实例>>>frombs4importBeautifulSoup>>>soup=BeautifulSoup(html_doc,"lxml")>>>print(soup.body.contents)[<pclass="title"><b>BigDataSoftware</b></p>,'\n',<pclass="bigdata">Therearethreefamousbigdatasoftwares;andtheirnamesare<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>and<aclass="software"href="/flink"id="link3">Flink</a>;andtheyarewidelyusedinrealapplications.</p>,'\n',<pclass="bigdata">...</p>,'\n']解析网页>>>print(soup.body.contents[0])<pclass="title"><b>BigDataSoftware</b></p>【例】使用索引的方式来获取列表中的元素解析网页遍历文档树——直接子节点Tag对象的.children属性是一个迭代器.children属性>>>forchildinsoup.body.children:print(child)可以使用for循环进行遍历,代码如下解析网页【例】.children属性使用for循环进行遍历的执行结果如下<pclass="title"><b>BigDataSoftware</b></p><pclass="bigdata">Therearethreefamousbigdatasoftwares;andtheirnamesare<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>and<aclass="software"href="/flink"id="link3">Flink</a>;andtheyarewidelyusedinrealapplications.</p><pclass="bigdata">...</p>解析网页所有子孙节点在获取所有子孙节点时使用descendants属性与Tag对象的.children和.contents仅包含Tag对象不同将Tag对象所有子孙结点进行递归循环,生成生成器解析网页>>>forchildinsoup.descendants:

print(child)所有子孙节点

最外层的

html

标签其次从head标签一个个剥离解析网页>>>print(soup.title)<title>BigDataSoftware</title>>>>print(soup.title.string)BigDataSoftware【例】Tag对象内没有标签的情况实例解析网页>>>print(soup.head)<head><title>BigDataSoftware</title></head>>>>print(soup.head.string)BigDataSoftware【例】Tag对象内有一个标签的情况的具体操作实例解析网页【例】Tag对象内有多个标签的情况,具体操作实例如下>>>print(soup.body)<body><pclass="title"><b>BigDataSoftware</b></p><pclass="bigdata">Therearethreefamousbigdatasoftwares;andtheirnamesare<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>and<aclass="software"href="/flink"id="link3">Flink</a>;andtheyarewidelyusedinrealapplications.</p><pclass="bigdata">...</p></body>解析网页如果使用.string获取子节点内容,就会返回None>>>print(soup.body.string)None应使用.strings属性或.stripped_strings属性,获得一个生成器>>>print(soup.strings)<generatorobjectTag._all_stringsat0x0000000002C4D190>解析网页如果Tag包含了多个子节点,Tag就无法确定.string应该调用哪个子节点的内容.stringKeywordNone使用.strings属性或.stripped_strings属性生成器解析网页>>>forstringinsoup.strings:print(repr(string))可以用for循环对生成器进行遍历,代码如下Tag对象内有多个标签的情况解析网页【例】上面代码的执行结果如下'BigDataSoftware''\n''BigDataSoftware''\n''Therearethreefamousbigdatasoftwares;andtheirnamesare\n''Hadoop'',\n''Spark''and\n''Flink'';\nandtheyarewidelyusedinrealapplications.''\n''...''\n'解析网页>>>forstringinsoup.stripped_strings:

print(string).stripped_strings属性

.stripped_strings属性去掉空白行的标签内的众多内容解析网页【例】上面代码的执行结果如下BigDataSoftwareBigDataSoftwareTherearethreefamousbigdatasoftwares;andtheirnamesareHadoop,SparkandFlink;andtheyarewidelyusedinrealapplications....解析网页.parent

属性01.parents

属性02可以获得父节点可以获得从父到根的所有节点直接父节点解析网页>>>p=soup.p>>>print()body【例】下面是获取标签的父节点实例解析网页>>>content=soup.head.title.string>>>print(content)BigDataSoftware>>>print()title【例】下面是获取内容的父节点实例解析网页

>>>content=soup.head.title.string

>>>print(content)

BigDataSoftware

>>>forparentincontent.parents:

print()

title

head

html

[document]【例】

Tag对象.parents属性,得到一个生成器执行结果解析网页兄弟节点.next_sibling.previous_sibling获取下一个兄弟结点属性通常是字符串空白也可被视作一个节点获取上一个兄弟结点属性通常是空白换行也可被视作一个节点得到结果可能是空白1234得到结果可能是换行1234解析网页【例】兄弟节点next_sibling和.previous_sibling属性,具体操作实例如下>>>print(soup.p.next_sibling)#此处返回为换行>>>print(soup.p.prev_sibling)None#没有前一个兄弟节点,返回None>>>print(soup.p.next_sibling.next_sibling)<pclass="bigdata">Therearethreefamousbigdatasoftwares;andtheirnamesare<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>and<aclass="software"href="/flink"id="link3">Flink</a>;andtheyarewidelyusedinrealapplications.</p>解析网页全部兄弟节点用.next_siblings和.previous_siblings属性对当前的兄弟结点迭代输出>>>fornextinsoup.a.next_siblings:

print(repr(next))上面全部兄弟节点的实例执行结果如下',\n'<aclass="software"href="/spark"id="link2">Spark</a>'and\n'<aclass="software"href="/flink"id="link3">Flink</a>';\nandtheyarewidelyusedinrealapplications.'解析网页前后节点>>>print(soup.head.next_element)<title>BigDataSoftware</title>用于获得不分层次的前后元素,示例代码如下.next_element.previous_element解析网页所有前后节点>>>forelementinsoup.a.next_elements:print(repr(element))用于获得不分层次的前后元素,示例代码如下.next_elements.previous_elements解析网页所有前后节点执行结果'Hadoop'',\n'<aclass="software"href="/spark"id="link2">Spark</a>'Spark''and\n'<aclass="software"href="/flink"id="link3">Flink</a>'Flink'';\nandtheyarewidelyusedinrealapplications.''\n'<pclass="bigdata">...</p>'...''\n'解析网页搜索文档树搜索文档树指定标签名指定标签属性值精确定位某个节点元素解析网页搜索文档树find()find_all()在BeatifulSoup和Tag对象上都可被调用解析网页find_all()find_all(name,attrs,recursive,text,**kwargs)搜索当前Tag的所有Tag子节点,并判断是否符合过滤器的条件find_all()返回值

是一个Tag组成的列表,方法调用灵活,所有参数可选解析网页name参数可以查找所有名字为name的Tag,字符串对象会被自动忽略掉name参数解析网页【例】传入字符串:查找所有名字为a的Tag,代码如下>>>print(soup.find_all('a'))[<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>,<aclass="software"href="/flink"id="link3">Flink</a>]解析网页>>>importre>>>fortaginsoup.find_all(pile("^b")):

print(tag)传入正则表达式

BeautifulSoup通过

match()

来匹配内容解析网页【例】传入正则表达式要找出所有以b开头的标签,执行结果如下<body><pclass="title"><b>BigDataSoftware</b></p><pclass="bigdata">Therearethreefamousbigdatasoftwares;andtheirnamesare<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>and<aclass="software"href="/flink"id="link3">Flink</a>;andtheyarewidelyusedinrealapplications.</p><pclass="bigdata">...</p></body><b>BigDataSoftware</b>解析网页>>>print(soup.find_all(["a","b"]))[<b>BigDataSoftware</b>,<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>,<aclass="software"href="/flink"id="link3">Flink</a>]【例】

如果传入参数是列表,BeautifulSoup会将与列表中任一元素匹配的内容返回找到所有<a>标签和<b>标签解析网页>>>print(soup.find_all(id=True))[<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>,<aclass="software"href="/flink"id="link3">Flink</a>]【例】

传入True可找到所有的标签。下面的例子是在文档树中查找所有包含id属性的标签传入True解析网页传入方法如果没有合适过滤器,那么可以定义一个方法方法只接受一个元素参数返回True当前元素匹配并且被找到返回False当前元素不匹配且没有被找到解析网页传入方法>>>defhas_class_but_no_id(tag):

returntag.has_attr('class')andnottag.has_attr('id')下面对当前元素进行校验,如包含class属性却不包含id属性,返回True如果这个方法返回True,表示当前元素匹配并且被找到,如果不是则返回False解析网页【例】将这个方法作为参数传入find_all()方法,将得到所有<p>标签>>>print(soup.find_all(has_class_but_no_id))[<pclass="title"><b>BigDataSoftware</b></p>,<pclass="bigdata">Therearethreefamousbigdatasoftwares;andtheirnamesare<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>and<aclass="software"href="/flink"id="link3">Flink</a>;andtheyarewidelyusedinrealapplications.</p>,<pclass="bigdata">...</p>]解析网页keyword参数name

参数搜索Tag的标签类型名称aheadtitle解析网页>>>importre>>>print(soup.find_all(id='link2'))[<aclass="software"href="/spark"id="link2">Spark</a>]>>>print(soup.find_all(href=pile("spark")))[<aclass="software"href="/spark"id="link2">Spark</a>]【例】

如果要通过标签内属性的值来搜索,要通过键值对的形式来指定,实例如下解析网页>>>soup.find_all(href=pile("hadoop"),id='link1')[<aclass="software"href="/hadoop"id="link1">Hadoop</a>]使用多个指定名字的参数可以同时过滤Tag的多个属性>>>print(soup.find_all(class_="software"))[<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>,<aclass="software"href="/flink"id="link3">Flink</a>]如果指定的key是Python的关键词,则后面需要加下划线解析网页text

参数name

参数搜索字符串内容(不含注释)text

参数解析网页【例】text参数搜索范围是文档中的字符串内容,也接受正则表达式、列表、True实例>>>importre>>>print(soup.a)<aclass="software"href="/hadoop"id="link1">Hadoop</a>>>>print(soup.find_all(text="Hadoop"))['Hadoop']>>>print(soup.find_all(text=["Hadoop","Spark","Flink"]))['Hadoop','Spark','Flink']>>>print(soup.find_all(text="bigdata"))[]>>>print(soup.find_all(text="BigDataSoftware"))['BigDataSoftware','BigDataSoftware']>>>print(soup.find_all(text=pile("bigdata")))['Therearethreefamousbigdatasoftwares;andtheirnamesare\n']解析网页limit参数name参数可以查找所有名字为name的Tag,字符串对象会被自动忽略掉limit

参数解析网页【例】通过limit参数来限制使用name参数或attrs参数过滤出来的条目的数量实例>>>print(soup.find_all("a"))[<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>,<aclass="software"href="/flink"id="link3">Flink</a>]>>>print(soup.find_all("a",limit=2))[<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>]解析网页调用Tag的find_all()方法时BeautifulSoup会检索当前Tag的所有子孙节点,如果只想搜索Tag的直接子节点,可以使用参数recursive=Falserecursive参数recursive参数解析网页>>>print(soup.body.find_all("a",recursive=False))[]recursive参数

a

标签是在

p

标签内无法匹配到

a

标签解析网页find()find_all()find()将所有匹配的条目组合成一个列表仅返回第一个匹配的条目解析网页CSS选择器BeautifulSoupCSS选择器select()

方法传入字符串参数解析网页>>>print(soup.select('title'))[<title>BigDataSoftware</title>]>>>print(soup.select('a'))[<aclass="software"href="/hadoop"id="link1">Hadoop</a>,<aclass="software"href="/spark"id="link2">Spark</a>,<aclass="software"href="/flink"id="link3">Flink</a>]>>>print(soup.select('b'))[<b>BigDataSoftware</b>]【例】CSS选择器,通过标签名查找,具体实例如下解析网页>>>print(soup.select('.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论