Beautiful Soup 中文文档之三

输出文档

你可以使用 str函数将Beautiful Soup文档(或者它的子集)转换为字符串,或者使用它的code>prettify或renderContents。你也可以使用unicode函数以Unicode字符串的形式获得。 prettify 方法添加了一些换行和空格以便让文档结构看起来更清晰。它也将那些只包含空白符的,可能影响一个XML文档意义的文档节点(nodes)剔除(strips out)。 strunicode函数不会剔除这些节点,他们也不会添加任何空白符。 看看这个例子:
from BeautifulSoup import BeautifulSoup
doc = "<html><h1>Heading</h1><p>Text"
soup = BeautifulSoup(doc)

str(soup)#'<html><h1>Heading</h1><p>Text</p></html>'
soup.renderContents()#'<html><h1>Heading</h1><p>Text</p></html>'
soup.__str__()#'<html><h1>Heading</h1><p>Text</p></html>'
unicode(soup)#u'<html><h1>Heading</h1><p>Text</p></html>'

soup.prettify()#'<html>n <h1>n Headingn </h1>n <p>n Textn </p>n</html>'

print soup.prettify()#<html>#<h1>#Heading#</h1>#<p>#Text#</p>#</html>
可以看到使用文档中的tag成员时 strrenderContents返回的结果是不同的。
heading = soup.h1
str(heading)#'<h1>Heading</h1>'
heading.renderContents()#'Heading'
当你调用__str__,prettify或者renderContents时,你可以指定输出的编码。默认的编码(str使用的)是UTF-8。下面是处理ISO-8851-1的串并以不同的编码输出同样的串的例子。
from BeautifulSoup import BeautifulSoup
doc = "Sacrxe9 bleu!"
soup = BeautifulSoup(doc)
str(soup)#'Sacrxc3xa9 bleu!' # UTF-8
soup.__str__("ISO-8859-1")#'Sacrxe9 bleu!'
soup.__str__("UTF-16")#'xffxfeSx00ax00cx00rx00xe9x00 x00bx00lx00ex00ux00!x00'
soup.__str__("EUC-JP")#'Sacrx8fxabxb1 bleu!'
如果原始文档含有编码声明,Beautiful Soup会将原始的编码声明改为新的编码。也就是说,你载入一个HTML文档到BeautifulSoup后,在输出它,不仅HTML被清理过了,而且可以明显的看到它已经被转换为UTF-8。 这是HTML的例子:
from BeautifulSoup import BeautifulSoup
doc = """<html>
<meta http-equiv="Content-type" content="text/html; charset=ISO-Latin-1" >
Sacrxe9 bleu!
</html>"""

print BeautifulSoup(doc).prettify()#<html>#<meta http-equiv="Content-type" content="text/html; charset=utf-8" />#Sacré bleu!#</html>
这是XML的例子:
from BeautifulSoup import BeautifulStoneSoup
doc = """<?xml version="1.0" encoding="ISO-Latin-1">Sacrxe9 bleu!"""

print BeautifulStoneSoup(doc).prettify()#<?xml version='1.0' encoding='utf-8'>#Sacré bleu!

剖析树

到目前为止,我们只是载入文档,然后再输出它。现在看看更让我们感兴趣的剖析树: Beautiful Soup剖析一个文档后生成的数据结构。 剖析对象 (BeautifulSoupBeautifulStoneSoup的实例)是深层嵌套(deeply-nested), 精心构思的(well-connected)的数据结构,可以与XML和HTML结构相互协调。剖析对象包括2个其他类型的对象,Tag对象,用于操纵像<TITLE> ,<B>这样的标签;NavigableString对象,用于操纵字符串,如"Page title"和"This is paragraph"。 NavigableString的一些子类 (CData, Comment, Declaration, and ProcessingInstruction), 也处理特殊XML结构。 它们就像NavigableString一样, 除了但他们被输出时,他们会被添加一些额外的数据。下面是一个包含有注释(comment)的文档:
from BeautifulSoup import BeautifulSoup
import re
hello = "Hello! <!--I've got to be nice to get what I want.-->"
commentSoup = BeautifulSoup(hello)
comment = commentSoup.find(text=re.compile("nice"))

comment.__class__#<class 'BeautifulSoup.Comment'>
comment#u"I've got to be nice to get what I want."
comment.previousSibling#u'Hello! '

str(comment)#"<!--I've got to be nice to get what I want.-->"
print commentSoup#Hello! <!--I've got to be nice to get what I want.-->
现在,我们深入研究一下我们开头使用的那个文档:
from BeautifulSoup import BeautifulSoup 
doc = ['<html><head><title>Page title</title></head>',
 '<body><p id="firstpara" align="center">This is paragraph <b>one</b>.',
 '<p id="secondpara" align="blah">This is paragraph <b>two</b>.',
 '</html>']
soup = BeautifulSoup(''.join(doc))

print soup.prettify()#<html>#<head>#<title>#Page title#</title>#</head>#<body>#<p id="firstpara" align="center">#This is paragraph#<b>#one#</b>#.#</p>#<p id="secondpara" align="blah">#This is paragraph#<b>#two#</b>#.#</p>#</body>#</html>

Tag的属性

TagNavigableString对象有很多有用的成员,在 Navigating剖析树Searching剖析树中我们会更详细的介绍。 现在,我们先看看这里使用的Tag成员:属性 SGML标签有属性:.例如,在上面那个HTML 中每个<P>标签都有"id"属性和"align"属性。你可以将Tag看成字典来访问标签的属性:
firstPTag, secondPTag = soup.findAll('p')

firstPTag['id']#u'firstPara'

secondPTag['id']#u'secondPara'
NavigableString对象没有属性;只有Tag 对象有属性。