输出
格式化输出,使用prettify()方法将BeautifulSoup文档树格式化以后以Unicode编码输出,每个XML/HTML标签单独占一行
markup = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(markup,"html.parser")
print(soup.prettify())
"""
<a href="http://example.com/">
I linked to
<i>
example.com
</i>
</a>
"""
上面是使用soup对象调用prettify,还可以使用tag节点,例如:
a_tag = soup.a
print(a_tag.prettify())
"""
<a href="http://example.com/">
I linked to
<i>
example.com
</i>
</a>
"""
压缩输出
对于只想输出结果为字符串,不在乎格式的可以使用BeautifulSoup对象或者tag对象的unicode()或str()方法,注意unicode是python2.x中的方法,在python3中已取消str()与unicode方法的区别
markup = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(markup,"html.parser")
print(str(soup))
# <a href="http://example.com/">I linked to <i>example.com</i></a>
输出格式
Beautiful Soup输出是会将HTML中的特殊字符转换成Unicode,比如“&lquot;”:
soup = BeautifulSoup("“Dammit!” he said.")
print(unicode(soup))
# <html><head></head><body>\u201cDammit!\u201d he said.</body></html>
get_text()方法
获取tag包含的文本内容,可以调用get_text()方法,这个方法获取到tag中包含的所有内容包括子tag节点
markup = '<a href="http://example.com/">\nI linked to <i>example.com</i>\n</a>'
soup = BeautifulSoup(markup,"html.parser")
print(soup.get_text())
# I linked to example.com
指定文档解析器
如果不指定文档解析器,BeautifulSoup会自动找到一个最合适的解析器,但是我们没法保证相同的代码在不同系统下运行结果,所以最好还是指定好解析器;BeautifulSoup()的第一个参数就是要解析的文档字符串或是文档句柄,第二个参数用来标识怎样来解析文档
-
支持解析的类型:html、xml、html5
-
指定哪种解析器:lxml、html5lib、html.parser
解析器之间的区别,这里需要先安装lxml库
解析成html结构
soup = BeautifulSoup('<a><b /></a>')
print(soup)
# <html><body><a><b></b></a></body></html>
同样的文档解析成xml结构
soup = BeautifulSoup('<a><b /></a>',"xml")
print(soup)
# <?xml version="1.0" encoding="utf-8"?>
# <a><b/></a>
HTML解析器之间也有区别,如果被解析的HTML文档是标准格式,那么解析器之间没有任何差别,只是解析速度不同,结果都会返回正确的文档树;但是如果被解析文档不是标准格式,那么不同的解析器返回结果可能不同.下面例子中,使用lxml解析错误格式的文档,结果
标签被直接忽略掉了
soup = BeautifulSoup("<a></p>", "lxml")
print(soup)
# <html><body><a></a></body></html>
使用html5lib库解析相同文档会得到不同的结果
soup = BeautifulSoup("<a></p>","html5lib")
print(soup)
# <html><head></head><body><a><p></p></a></body></html>)
使用python内置库解析相同文档结果
soup = BeautifulSoup("<a></p>","html.parser")
print(soup)
# <a></a>
编码
任何html或xml文档被BeautifulSoup解析后都会变成Unicode编码格式,通过BeautifulSoup对象的
.original_encoding
属性记录了自动识别编码的结果,我们可以在创建BeautifulSoup 对象的时候设置 from_encoding 参数来指定编码格式
输出编码
通过Beautiful Soup输出文档时,不管输入文档是什么编码方式,输出编码均为UTF-8编码
markup = b'''
<html>
<head>
<meta content="text/html; charset=ISO-Latin-1" http-equiv="Content-type" />
</head>
<body>
<p>Sacr\xe9 bleu!</p>
</body>
</html>
'''
soup = BeautifulSoup(markup,"html5lib")
print(soup.prettify())
"""
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-type"/>
</head>
<body>
<p>
Sacré bleu!
</p>
</body>
</html>
"""
如果不想用UTF-8编码输出,可以将编码方式传入 prettify() 方法
比较对象是否相同
两个 NavigableString 或 Tag 对象具有相同的HTML或XML结构时, Beautiful Soup就判断这两个对象相同
markup = "<p>I want <b>pizza</b> and more <b>pizza</b>!</p>"
soup = BeautifulSoup(markup, 'html.parser')
first_b, second_b = soup.find_all('b')
print(first_b == second_b)
# True
如果要严格判断两个对象是否完全指向一个对象,可以使用is
print(first_b is second_b)
# False
解析部分文档
如果仅仅因为想要查找文档中的标签而将整片文档进行解析,实在是浪费内存和时间.最快的方法是从一开始就把标签以外的东西都忽略掉.
SoupStrainer 类可以定义文档的某段内容,这样搜索文档时就不必先解析整篇文档,只会解析在 SoupStrainer 中定义过的文档.
创建一个 SoupStrainer 对象并作为 parse_only 参数给 BeautifulSoup 的构造方法即可.
SoupStrainer 对象
from bs4 import SoupStrainer
# 三种SoupStrainer对象
only_a_tags = SoupStrainer("a")
only_tags_with_id_link2 = SoupStrainer(id="link2")
def is_short_string(string):
return len(string) < 10
# 传入对象参数
only_short_strings = SoupStrainer(string=is_short_string)
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><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>
"""
print(BeautifulSoup(html_doc, "html.parser", parse_only=only_a_tags).prettify())
# <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>
print(BeautifulSoup(html_doc, "html.parser", parse_only=only_tags_with_id_link2).prettify())
# <a class="sister" href="http://example.com/lacie" id="link2">
# Lacie
# </a>
print(BeautifulSoup(html_doc, "html.parser", parse_only=only_short_strings).prettify())
# Elsie
# ,
# Lacie
# and
# Tillie
# ...
#