【Python爬虫学习笔记(3)】Beautiful Soup库相关知识点总结
1. Beautiful Soup简介
Beautiful Soup是将数据从HTML和XML文件中解析出来的一个python库,它能够提供一种符合习惯的方法去遍历搜索和修改解析树,这将大大减少爬虫程序的运行时间。
Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。
2. Beautiful Soup安装
利用pip可以迅速安装,目前最新版本为BeautifulSoup4。
$ pip install beautifulsoup4安装后,import一下bs4就可以使用了。
from bs4 import BeautifulSoup3. 创建Beautiful Soup对象
我们利用以下测试文件来进行之后的总结。
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""import之后,创建一个BeautifulSoup对象如下参数可以是一个抓取到的unicode格式的网页html,也可以是一个已经保存到本地的html文件test.html。
soup = BeautifulSoup(html)
soup = BeautifulSoup(open('test.html'))创建后查看是否创建成功。注意:有时需要在后面加上encode('utf-8')来进行编码才能将soup对象正确显示出来。
print soup.prettify()4. 四种Beautiful Soup对象类型
Beautiful Soup一共有四大对象种类,包括Tag,NavigableString,BeautifulSoup和Comment。
4.1 Tag
Tag对象
Tag就是html文件中的标签以及标签之间的内容,例如以下就是一个Tag。
<title>The Dormouse's story</title>可以这样得到title这个Tag,第二行为运行结果。
print soup.title
#<title>The Dormouse's story</title>注意:如果得到的是'bs4.element.Tag'类型的对象可以继续进行后续的.操作,即能进行soup对象所能进行的操作,所以需要确保一个对象是'bs4.element.Tag'类型后再进行后续对其的操作,例如后面将介绍的.find方法是Tag对象才拥有的。
print type(soup.title)
#<class 'bs4.element.Tag'>Tag方法
.name
Tag对象的.name方法得到的是该Tag的标签本身名称。
print soup.title.name
#title.attrs
Tag对象的.attrs将得到标签中所有属性的字典。
print soup.p.attrs
#{'class': ['title'], 'name': 'dromouse'}可以对Tag对象进行字典可以进行的操作,例如修改,删除,读取等。
print soup.p['class']#读取(方法一)
#['title']
print soup.p.get('class')#读取(方法二)
#['title'] soup.p['class']="newClass"#修改
print soup.p
#<p class="newClass" name="dromouse"><b>The Dormouse's story</b></p> del soup.p['class']#删除
print soup.p
#<p name="dromouse"><b>The Dormouse's story</b></p>4.2 NavigableString
标签内部的内容由.string方法可以得到,且这些内容为'bs4.element.NavigableString'类型的对象。
print soup.p.string
#The Dormouse's story print type(soup.p.string)
#<class 'bs4.element.NavigableString'>4.3 BeautifulSoup
BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,是一个特殊的 Tag。
print type(soup.name)
#<type 'unicode'>
print soup.name
# [document]
print soup.attrs
#{} 空字典4.4 Comment
前三种类型几乎涵盖了在HTML或者XML中所有的内容,但是Comment类型是需要关心的一种,和CData,ProcessingInstruction,Declaration,Doctype一样,它是NavigableString类型的一个子类,通过以下代码可以简单了解它的功能。
markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"#标签中内容为注释
soup = BeautifulSoup(markup)
comment = soup.b.string
type(comment)
# <class 'bs4.element.Comment'>
comment
# u'Hey, buddy. Want to buy a used parser'
print(soup.b.prettify())
# <b>
# <!--Hey, buddy. Want to buy a used parser?-->
# </b>注意:标签里的内容实际上是注释,但是如果我们利用 .string 来输出它的内容,我们发现它已经把注释符号去掉了,所以这可能会给我们带来不必要的麻烦,需要在使用或者进行一些操作 之前进行类型判断。
if type(soup.b.string)==bs4.element.Comment:
...5. 树的遍历
5.1 子孙节点
.content
Tag对象的.content方法可以得到其子节点的一个列表表示。
print soup.head.contents
#[<title>The Dormouse's story</title>]当然,既然是列表可以用索引直接得到某一项。
print soup.head.contents[0]
#<title>The Dormouse's story</title>.children
Tag对象的.children方法得到一个其子节点的迭代器,可以遍历之获取其中的元素。
for child in soup.body.children:
print child.descendants
与.content和.children只得到直接子节点不同,.descendants能对所有子孙节点迭代循环,将标签层层剥离得到所有子节点,同样通过遍历的方法得到每个子孙节点。
for child in soup.descendants:
print child5.2 父亲节点
.parent
Tag对象的.parent方法能得到其直接父节点。
.parents
用.parents属性可以递归得到元素的所有父节点。
content = soup.head.title.string
for parent in content.parents:
print parent.name
#title
#head
#html
#[document]5.3 兄弟节点
.next_sibling和.next_siblings
.next_sibling得到Tag对象平级的下一个节点,如果不存在则返回None。.next_siblings得到Tag对象平级的下面所有兄弟节点。
.previous_sibling和.previous_siblings
.previous_sibling得到Tag对象平级的上一个节点,如果不存在则返回None。.next_siblings得到Tag对象平级的上面所有兄弟节点。
注意:由于在HTML文档中的空白和换行也被视作是一个节点,所以可能得到的兄弟节点(或者子节点父节点)会是空白类型或者字符串类型而不是Tag,所以在进行下一步操作时一定要先用type函数进行类型的判断。
5.4 前后节点
.next_element和.next_elements
与 .next_sibling和.next_siblings 不同,它并不是针对于兄弟节点,而是在所有节点,不分层次得到下一个节点和所有的后续节点。.next_elements的结果通过遍历访问。
.previous_element和.previous_elements
这两个方法将不分层次得到上一个节点和所有之前的节点。.previous_elements的结果通过遍历访问。
5.4 节点内容
.string
如果一个标签里面没有标签了,那么 .string 就会返回标签里面的内容。如果标签里面只有唯一的一个标签了,那么 .string 也会返回最里面的内容。
print soup.head.string
#The Dormouse's story
print soup.title.string
#The Dormouse's story而如果Tag包含了多个子节点,Tag就无法确定.string 方法应该调用哪个子节点的内容,输出结果是 None。
.strings和.stripped_strings
当一个Tag对象有多个子节点时,可以用.strings方法再通过遍历获得所有子节点的内容。
for string in soup.strings:
print(repr(string))
# u"The Dormouse's story"
# u'\n\n'
# u"The Dormouse's story"
# u'\n\n'
# u'Once upon a time there were three little sisters; and their names were\n'
# u'Elsie'
# u',\n'
# u'Lacie'
# u' and\n'
# u'Tillie'
# u';\nand they lived at the bottom of a well.'
# u'\n\n'
# u'...'
# u'\n'用.stripped_strings方法可以得到过滤掉空格和空行的内容。
.get_text()
如果你仅仅想要得到文档或者标签的文本部分,可以使用.get_text()方法,它能以一个单一的一个Unicode串的形式返回文档中或者Tag对象下的所有文本。
markup = '<a href="http://example.com/">\nI linked to <i>example.com</i>\n</a>'
soup = BeautifulSoup(markup) soup.get_text()
#u'\nI linked to example.com\n'
soup.i.get_text()
#u'example.com'你可以指定一个字符串来连接文本的位。
soup.get_text("|")
#u'\nI linked to |example.com|\n'进一步,通过strip去除掉文本每个位的头尾空白。
soup.get_text("|", strip=True)
#u'I linked to|example.com'用列表推导式以及.stripped_strings方法罗列出文本内容。
[text for text in soup.stripped_strings]
#[u'I linked to', u'example.com']6. 树的搜索
6.1 find_all(name, attrs, recursive, string, limit, **kwargs)
该方法将搜索当前Tag对象的所有子节点,并且按照过滤条件得到筛选后对象的列表。
name参数
1)传字符串
最简单的方法是传入标签名的字符串,可以得到所有以该字符串为标签名的一个列表。
print soup.find_all('a')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]2)传正则表达式
可以通过传正则表达式得到符合表达式规则的Tag对象。
import re
for tag in soup.find_all(re.compile("^b")):
print(tag.name)
# body
# b3)传列表
可以传入一个字符串的列表,将匹配列表中标签的Tag全部返回。
soup.find_all(["a", "b"])
# [<b>The Dormouse's story</b>,
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]4)传True
True参数将匹配文档中所有的节点,但是不包括文本字符串。
for tag in soup.find_all(True):
print(tag.name)
# html
# head
# title
# body
# p
# b
# p
# a
# a
# a
# p5)传入函数
可以根据函数返回值的True/False来得到匹配的节点。
def has_class_but_no_id(tag):
return tag.has_attr('class') and not tag.has_attr('id') soup.find_all(has_class_but_no_id)
# [<p class="title"><b>The Dormouse's story</b></p>,
# <p class="story">Once upon a time there were...</p>,
# <p class="story">...</p>]关键字参数
可以传入一个或者多个关键字,BeautifulSoup会搜索当前Tag下的每一个节点的该关键字及其对应的值。
soup.find_all(href=re.compile("elsie"), id='link1')
# [<a class="sister" href="http://example.com/elsie" id="link1">three</a>]特殊:如果希望用class及其值作为过滤条件,由于class是python的关键字,所以需要作如下处理。
soup.find_all("a", class_="sister")
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]另外,有些tag属性在搜索不能使用,比如HTML5中的 data-* 属性,可以这样来进行过滤。
data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')
data_soup.find_all(attrs={"data-foo": "value"})
# [<div data-foo="value">foo!</div>]text参数
可以在文档中搜索一些字符串内容,与name参数的可选值一样,可以传字符串,列表,正则表达式和True。
soup.find_all(text="Elsie")
# [u'Elsie'] soup.find_all(text=["Tillie", "Elsie", "Lacie"])
# [u'Elsie', u'Lacie', u'Tillie'] soup.find_all(text=re.compile("Dormouse"))
[u"The Dormouse's story", u"The Dormouse's story"]limit参数
可用该参数限制返回的节点数目,例子中本身有3个符合的节点,仅输出两个。
soup.find_all("a", limit=2)
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]recursive参数
将该参数设为False可限制只搜索当前Tag的直接子节点,可以节省很多搜索时间。
soup.html.find_all("title")
# [<title>The Dormouse's story</title>]
soup.html.find_all("title", recursive=False)
# []6.2. find( name , attrs , recursive , text , **kwargs )
它与 find_all() 方法唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果
6.3. find_parents()和find_parent()
find_all() 和 find() 只搜索当前节点的所有子节点,孙子节点等. find_parents() 和 find_parent() 用来搜索当前节点的父辈节点,搜索方法与普通tag的搜索方法相同,搜索文档搜索文档包含的内容
6.4. find_next_siblings()和find_next_sibling()
这2个方法通过 .next_siblings 属性对当 tag 的所有后面解析的兄弟 tag 节点进行迭代, find_next_siblings() 方法返回所有符合条件的后面的兄弟节点,find_next_sibling() 只返回符合条件的后面的第一个tag节点
6.5. find_previous_siblings()和find_previous_sibling()
这2个方法通过 .previous_siblings 属性对当前 tag 的前面解析的兄弟 tag 节点进行迭代, find_previous_siblings()方法返回所有符合条件的前面的兄弟节点, find_previous_sibling() 方法返回第一个符合条件的前面的兄弟节点。
6.6. find_all_next()和find_next()
这2个方法通过 .next_elements 属性对当前 tag 的之后的 tag 和字符串进行迭代, find_all_next() 方法返回所有符合条件的节点, find_next() 方法返回第一个符合条件的节点
6.7. find_all_previous()和find_previous()
这2个方法通过 .previous_elements 属性对当前节点前面的 tag 和字符串进行迭代, find_all_previous() 方法返回所有符合条件的节点, find_previous()方法返回第一个符合条件的节点
参考资料:
http://www.crummy.com/software/BeautifulSoup/bs4/doc/#
转载请注明:
http://www.cnblogs.com/wuwenyan/p/4773427.html
【Python爬虫学习笔记(3)】Beautiful Soup库相关知识点总结的更多相关文章
- Python爬虫利器二之Beautiful Soup的用法
上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫Be ...
- 吴裕雄--天生自然python学习笔记:Beautiful Soup 4.2.0模块
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...
- python爬虫学习笔记(一)——环境配置(windows系统)
在进行python爬虫学习前,需要进行如下准备工作: python3+pip官方配置 1.Anaconda(推荐,包括python和相关库) [推荐地址:清华镜像] https://mirrors ...
- Python爬虫学习笔记之爬虫基础库
知识预览 beautifulsoup的简单使用 beautifulsoup的遍历文档树 beautifulsoup的搜索文档树 beautifulsoup的css选择器 回到顶部 beautifuls ...
- Python学习笔记之Beautiful Soup
如何在Python3.x中使用Beautiful Soup 1.BeautifulSoup中文文档:http://www.crummy.com/software/BeautifulSoup/bs3/d ...
- 一入爬虫深似海,从此游戏是路人!总结我的python爬虫学习笔记!
前言 还记得是大学2年级的时候,偶然之间看到了学长在学习python:我就坐在旁边看他敲着代码,感觉很好奇.感觉很酷,从那之后,我就想和学长一样的厉害,就想让学长教我,请他吃了一周的饭,他答应了.从此 ...
- python爬虫(7)--Beautiful Soup的用法
1.Beautiful Soup简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据. Beautiful Soup提供一些简单的.python式的函数用来 ...
- Python爬虫学习笔记(三)
Cookies: 以抓取https://www.yaozh.com/为例 Test1(不使用cookies): 代码: import urllib.request # 1.添加URL url = &q ...
- Python爬虫学习笔记-1.Urllib库
urllib 是python内置的基本库,提供了一系列用于操作URL的功能,我们可以通过它来做一个简单的爬虫. 0X01 基本使用 简单的爬取一个页面: import urllib2 request ...
随机推荐
- Spring中RestTemplate进行Http调用
Spring中的RestTemplate类源自spring-web,http调用中设置超时时间.设置连接池管理等非常重要,保证了系统的可用性,避免了长时间连接不上或者等待数据返回,拖垮系统. 现贴出工 ...
- LightOJ 1341 Aladdin and the Flying Carpet(唯一分解定理)
http://lightoj.com/volume_showproblem.php?problem=1341 题意:给你矩形的面积(矩形的边长都是正整数),让你求最小的边大于等于b的矩形的个数. 思路 ...
- spring boot 知识点1
spring boot: 1. 可以在pom文件中添加依赖sping-boot-properties-migrator来对项目进行升级,升级完成后,删除即可. 2. 关于日志的配置,参考:http:/ ...
- spring boot2.1读取 apollo 配置中心3
上篇记录了springboot读取apollo的配置信息,以及如何获取服务端的推送更新配置. 接下来记录一下,如何获取公共namespace的配置. 上文中使用如下代码共聚公共命名空间的配置: @Ap ...
- PE文件格式学习之PE头移位
以前刚开始学网络安全,是从免杀开始的.记得那时候杀毒软件还很弱.金山江民瑞星还存在. 那会什么原理也不懂,就一直瞎鼓捣.(后来转入渗透行列了) 这段时间一直在学PE格式,突然想起来以前很古老的PE文件 ...
- Nordic官方网络资源介绍(官网/devzone/GitHub)
本文将介绍Nordic官方网络资源,包括Nordic官网,开发者论坛(devzone),以及Nordic在GitHub上的共享资源. 1. Nordic官网(产品/SDK/工具/文档库) Nordic ...
- Java中unicode增补字符(辅助平面)相关用法简介
转载自 http://blog.csdn.net/gjb724332682/article/details/51324036 前言 Java从1.5版本开始,加入了unicode辅助平面的支持.相关的 ...
- laravel5.5中查询构造器的使用
//查询构造器新增数据: public function query1() { /* $bool=DB::table('student')->insert( ['name'=>'小李',' ...
- ASP.NET MVC TryUpdateModel 更新model
总结参考:原文地址http://www.it165.net/pro/html/201305/5724.html TryUpdateModel (model)默认将view页面上form表单中的字段与m ...
- ZOJ 3521 Fairy Wars oj错误题目,计算几何,尺取法,排序二叉树,并查集 难度:2
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3521 ATTENTION:如果用long long 减小误差,这道题只能用 ...