1、Python 之 Beautiful Soup 4文档Python 之 Beautiful Soup 4文档(ps:其实入门什么的看官方文档是最好的了,这里只是记录一下简单的用法。)首先先介绍实际工作中最常用的几个方法:举例的html代码(就用官方例子好了): 1 2 3 Page title 4 5 6 7 This is paragraphone. 8 9 10 This is paragraphtwo.11 12 13 0、初始化:1 soup = BeautifulSoup(html) # html为html源代码字符串,type(html) = str1、用tag获取相应代码块的剖析
2、树:既然要分析html,首先要找到对我们有用的tag块,beautiful提供了非常便利的方式。#当用tag作为搜索条件时,我们获取的包含这个tag块的剖析树:#ooo#这里获取head这个块head = soup.find(head)# or# head = soup.head# or# head = soup.contents0.contents0运行后,我们会得到:1 2 Page title3 find方法在当前tag剖析树(当前这个html代码块中)寻找符合条件的子树并返回。find方法提供多种查询方式,包括用喜闻乐见的regex哦之后会详细介绍。contents属性是一个列表,里面
3、保存了该剖析树的直接儿子。如:1 html = soup.contents0 # . 2 head = html.contents0 # . 3 body = html.contents1 # . 2、用contents, parent, nextSibling, previousSibling寻找父子兄弟tag为了更加方便灵活的分析html代码块,beautifulSoup提供了几个简单的方法直接获取当前tag块的父子兄弟。假设我们已经获得了body这个tag块,我们想要寻找, , 第一个, 第二个这四个tag块:# body = soup.bodyhtml = body.parent #
4、html是body的父亲head = body.previousSibling # head和body在同一层,是body的前一个兄弟p1 = body.contents0 # p1, p2都是body的儿子,我们用contents0取得p1p2 = p1.nextSibling # p2与p1在同一层,是p1的后一个兄弟, 当然body.content1也可得到print p1.text# uThis is paragraphone.print p2.text# uThis is paragraphtwo.# 注意:1,每个tag的text包括了它以及它子孙的text。2,所有text已经被
5、自动转#为unicode,如果需要,可以自行转码encode(xxx)然而,如果我们要寻找祖先或者孙子tag怎么办呢? 用while循环吗? 不, beautifulsoup已经提供了方法。3、用find, findParent, findNextSibling, findPreviousSibling寻找祖先或者子孙 tag:有了上面的基础,这里应该很好理解了,例如find方法(我理解和findChild是一样的),就是以当前节点为起始,遍历整个子树,找到后返回。而这些方法的复数形式,会找到所有符合要求的tag,以list的方式放回。他们的对应关系是:find-findall, findPa
6、rent-findParents, findNextSibling-findNextSiblings.如:1 print soup.findAll(p)2 # This is paragraph one., This is paragraph two.这里我们重点讲一下find的几种用法,其他的类比:find(name=None, attrs=, recursive=True, text=None, *kwargs)(ps:只讲几种用法,完整请看官方link :1) 搜索tag:1 find(tagname) # 直接搜索名为tagname的tag 如:find(head)2 find(lis
7、t) # 搜索在list中的tag,如: find(head, body)3 find(dict) # 搜索在dict中的tag,如:find(head:True, body:True)4 find(pile() # 搜索符合正则的tag, 如:find(pile(p) 搜索以p开头的tag5 find(lambda) # 搜索函数返回结果为true的tag, 如:find(lambda name: if len(name) = 1) 搜索长度为1的tag6 find(True) # 搜索所有tag2) 搜索属性(attrs):1 find(id=xxx) # 寻找id属性为xxx的2 fin
8、d(attrs=id=pile(xxx), algin=xxx) # 寻找id属性符合正则且algin属性为xxx的3 find(attrs=id=True, algin=None) # 寻找有id属性但是没有algin属性的3) 搜索文字(text):注意,文字的搜索会导致其他搜索给的值如:tag, attrs都失效。方法与搜索tag一致4) recursive, limit:recursive=False表示只搜索直接儿子,否则搜索整个子树,默认为True。当使用findAll或者类似返回list的方法时,limit属性用于限制返回的数量,如findAll(p, limit=2): 返回首
9、先找到的两个tag*4、用next,previous寻找上下文tag(少用)这里我们主要看看next, next是取得当前的tag的下一个(按代码从上到下的顺序)tag块。这与contents是不一样的,千万别混淆了哦 我们举个栗子来看看1 2 a3 b4 c5 我们看看next的实际效果:1 a = soup.a2 b = soup.b3 n1 = b.next4 n2 = n1.next输出一下:1 print a.next2 # ua3 print n14 # ub5 print n26 # c所以,next仅仅是获取文档上的“下一个”的tag,和剖析树中的位置无关。当然也有findNe
10、xt和findAllNext方法。至于previous, 表示上一个tag块,就类比一下吧 *完整版*Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.这篇文档介绍了BeautifulSoup4中所有主要特性,并切有小例子.让我来向你展示它适合做什么,如何工作,怎样使用,如何达到你想要的效果,和处理异常情况.文档中出现的例子在Python2.7和Python3.2中的执行结果相同你可能在寻找Beautiful Soup3的文档,
11、Beautiful Soup 3 目前已经停止开发,我们推荐在现在的项目中使用Beautiful Soup 4,移植到BS4寻求帮助如果你有关于BeautifulSoup的问题,可以发送邮件到讨论组.如果你的问题包含了一段需要转换的HTML代码,那么确保你提的问题描述中附带这段HTML文档的代码诊断1快速开始下面的一段HTML代码将作为例子被多次用到.这是爱丽丝梦游仙境的的一段内容(以后内容中简称为爱丽丝的文档):html_doc = The Dormouses storyThe Dormouses storyOnce upon a time there were three little s
12、isters; and their names wereElsie,Lacie andTillie;and they lived at the bottom of a well.使用BeautifulSoup解析这段代码,能够得到一个BeautifulSoup的对象,并能按照标准的缩进格式的结构输出:from bs4 import BeautifulSoupsoup = BeautifulSoup(html_doc)print(soup.prettify()# # # # The Dormouses story# # # # # # The Dormouses story# # # # Onc
13、e upon a time there were three little sisters; and their names were# # Elsie# # ,# # Lacie# # and# # Tillie# # ; and they lived at the bottom of a well.# # # .# # # 几个简单的浏览结构化数据的方法:soup.title# The Dormouses storysoup.title.name# utitlesoup.title.string# uThe Dormouses storysoup.title.parent.name# uh
14、eadsoup.p# The Dormouses storysoup.pclass# utitlesoup.a# Elsiesoup.find_all(a)# Elsie,# Lacie,# Tilliesoup.find(id=link3)# Tillie从文档中找到所有标签的链接:for link in soup.find_all(a): print(link.get(href) # # # 从文档中获取所有文字内容:print(soup.get_text()# The Dormouses story# The Dormouses story# Once upon a time there
15、 were three little sisters; and their names were# Elsie,# Lacie and# Tillie;# and they lived at the bottom of a well.# .这是你想要的吗?别着急,还有更好用的安装 Beautiful Soup如果你用的是新版的Debain或ubuntu,那么可以通过系统的软件包管理来安装:$apt-getinstallPython-bs4Beautiful Soup 4 通过PyPi发布,所以如果你无法使用系统包管理安装,那么也可以通过easy_install或pip来安装.包的名字是beau
16、tifulsoup4,这个包兼容Python2和Python3.$easy_installbeautifulsoup4$pipinstallbeautifulsoup4(在PyPi中还有一个名字是BeautifulSoup的包,但那可能不是你想要的,那是Beautiful Soup3的发布版本,因为很多项目还在使用BS3, 所以BeautifulSoup包依然有效.但是如果你在编写新项目,那么你应该安装的beautifulsoup4)如果你没有安装easy_install或pip,那你也可以下载BS4的源码,然后通过setup.py来安装.$Pythonsetup.pyinstall如果上述安
17、装方法都行不通,Beautiful Soup的发布协议允许你将BS4的代码打包在你的项目中,这样无须安装即可使用.作者在Python2.7和Python3.2的版本下开发Beautiful Soup, 理论上Beautiful Soup应该在所有当前的Python版本中正常工作安装完成后的问题Beautiful Soup发布时打包成Python2版本的代码,在Python3环境下安装时,会自动转换成Python3的代码,如果没有一个安装的过程,那么代码就不会被转换.如果代码抛出了ImportError的异常: “No module named HTMLParser”, 这是因为你在Python
18、3版本中执行Python2版本的代码.如果代码抛出了ImportError的异常: “No module named html.parser”, 这是因为你在Python2版本中执行Python3版本的代码.如果遇到上述2种情况,最好的解决方法是重新安装BeautifulSoup4.如果在ROOT_TAG_NAME = udocument代码处遇到SyntaxError“Invalid syntax”错误,需要将把BS4的Python代码版本从Python2转换到Python3. 可以重新安装BS4:$Python3setup.pyinstall或在bs4的目录中执行Python代码版本转换脚
19、本$2to3-3.2-wbs4安装解析器Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是lxml.根据操作系统不同,可以选择下列方法来安装lxml:$apt-getinstallPython-lxml$easy_installlxml$pipinstalllxml另一个可供选择的解析器是纯Python实现的html5lib, html5lib的解析方式与浏览器相同,可以选择下列方法来安装html5lib:$apt-getinstallPython-html5lib$easy_installhtml5lib$pipinstallhtml5
20、lib下表列出了主要的解析器,以及它们的优缺点:解析器使用方法优势劣势Python标准库BeautifulSoup(markup,html.parser) Python的内置标准库 执行速度适中 文档容错能力强 Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差lxml HTML 解析器BeautifulSoup(markup,lxml) 速度快 文档容错能力强 需要安装C语言库lxml XML 解析器BeautifulSoup(markup,lxml,xml)BeautifulSoup(markup,xml) 速度快 唯一支持XML的解析器 需要安装C语言库html5li
21、bBeautifulSoup(markup,html5lib) 最好的容错性 以浏览器的方式解析文档 生成HTML5格式的文档 速度慢 不依赖外部扩展推荐使用lxml作为解析器,因为效率更高. 在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定.提示: 如果一段HTML或XML文档格式不正确的话,那么在不同的解析器中返回的结果可能是不一样的,查看解析器之间的区别了解更多细节如何使用将一段文档传入BeautifulSoup 的构造方法,就能得到一个文档的对象, 可以传入一
22、段字符串或一个文件句柄.from bs4 import BeautifulSoupsoup = BeautifulSoup(open(index.html)soup = BeautifulSoup(data)首先,文档被转换成Unicode,并且HTML的实例都被转换成Unicode编码BeautifulSoup(Sacré bleu!)Sacr bleu!然后,Beautiful Soup选择最合适的解析器来解析这段文档,如果手动指定解析器那么Beautiful Soup会选择指定的解析器来解析文档.(参考解析成XML).对象的种类Beautiful Soup将复杂HTML文档
23、转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:Tag,NavigableString,BeautifulSoup,Comment.TagTag对象与XML或HTML原生文档中的tag相同:soup = BeautifulSoup(Extremely bold)tag = soup.btype(tag)# Tag有很多方法和属性,在遍历文档树和搜索文档树中有详细解释.现在介绍一下tag中最重要的属性: name和attributesName每个tag都有自己的名字,通过.name来获取:tag.name# ub如果改变了tag的name,那将影响所有通过当前Beautiful Soup对象生成的HTML文档:tag.name = blockquotetag# Extremely boldAttributes一个tag可能有很多个属性. tag有一个 “class” 的属性,值为 “boldest” .tag的属性的操作方法与字典相同:tagclass# uboldest也可以直接”点”取属性, 比如:.attrs:tag.attrs# uclass: uboldesttag的属性可以被添加,删除或修改. 再说一次, tag的属性操作方法与字典一样tagclass = veryboldtagid = 1
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1