Beautiful Soup4学习笔记(六):输出,编译器

输出

格式化输出

prettify() 方法将Beautiful Soup的文档树格式化后以Unicode编码输出,每个XML/HTML标签都独占一行

>>> markup = 'I linked to example.com' 
>>> soup = BeautifulSoup(markup) 
>>> soup.prettify()
'\n \n  \n   I linked to\n   \n    example.com\n   \n  \n \n'
>>> print(soup.prettify()) 

 
  
   I linked to
   
    example.com
   
  
 

BeautifulSoup 对象和它的tag节点都可以调用 prettify() 方法:

>>> print(soup.a.prettify()) 

 I linked to
 
  example.com
 

压缩输出

如果只想得到结果字符串,不重视格式,那么可以对一个 BeautifulSoup 对象或 Tag 对象使用Python的 unicode() 或 str() 方法:

>>> str(soup) 
'I linked to example.com'

str() 方法返回UTF-8编码的字符串,可以指定 编码 的设置.
还可以调用 encode() 方法获得字节码或调用 decode() 方法获得Unicode.

输出格式

Beautiful Soup输出是会将HTML中的特殊字符转换成Unicode,比如“&lquot;”:

soup = BeautifulSoup("“Dammit!” he said.")
unicode(soup)
# u'\u201cDammit!\u201d he said.'

如果将文档转换成字符串,Unicode编码会被编码成UTF-8.这样就无法正确显示HTML特殊字符了:

str(soup)
#'\xe2\x80\x9cDammit!\xe2\x80\x9d he said.'

注意:这里一直搞不清楚,所以直接复制了文档

get_text()

如果只想得到tag中包含的文本内容,那么可以调用 get_text() 方法,这个方法获取到tag中包含的所有文版内容包括子孙tag中的内容,并将结果作为Unicode字符串返回:

>>> markup = '\nI linked to example.com\n'
>>> soup = BeautifulSoup(markup)
>>> soup.get_text() 
'\nI linked to example.com\n'
>>> soup.i.get_text() 
'example.com'

可以通过参数指定tag的文本内容的分隔符:
>>> soup.get_text("/") 
'\nI linked to /example.com/\n'

还可以去除获得文本内容的前后空白:
>>> soup.get_text("/",strip=True) 
'I linked to/example.com'

或者使用 .stripped_strings 生成器,获得文本列表后手动处理列表:
>>> [text for text in soup.stripped_strings] 
['I linked to', 'example.com']

指定文档解析器

如果仅是想要解析HTML文档,只要用文档创建 BeautifulSoup 对象就可以了.Beautiful Soup会自动选择一个解析器来解析文档.但是还可以通过参数指定使用那种解析器来解析当前文档.

BeautifulSoup 第一个参数应该是要被解析的文档字符串或是文件句柄,第二个参数用来标识怎样解析文档.如果第二个参数为空,那么Beautiful Soup根据当前系统安装的库自动选择解析器,解析器的优先数序: lxml, html5lib, Python标准库.在下面两种条件下解析器优先顺序会变化:

* 要解析的文档是什么类型: 目前支持, “html”, “xml”, 和 “html5”
* 指定使用哪种解析器: 目前支持, “lxml”, “html5lib”, 和 “html.parser”

如果指定的解析器没有安装,Beautiful Soup会自动选择其它方案.目前只有 lxml 解析器支持XML文档的解析,在没有安装lxml库的情况下,创建 beautifulsoup 对象时无论是否指定使用lxml,都无法得到解析后的对象

解析器之间的区别

Beautiful Soup为不同的解析器提供了相同的接口,但解析器本身时有区别的.同一篇文档被不同的解析器解析后可能会生成不同结构的树型文档.区别最大的是HTML解析器和XML解析器,看下面片段被解析成HTML结构:

>>> BeautifulSoup("") 

因为空标签不符合HTML标准,所以解析器把它解析成

同样的文档使用XML解析如下(解析XML需要安装lxml库).注意,空标签依然被保留,并且文档前添加了XML头,而不是被包含在标签内:

>>> BeautifulSoup("", "xml") 


HTML解析器之间也有区别,如果被解析的HTML文档是标准格式,那么解析器之间没有任何差别,只是解析速度不同,结果都会返回正确的文档树.

但是如果被解析文档不是标准格式,那么不同的解析器返回结果可能不同.下面例子中,使用lxml解析错误格式的文档,结果

标签被直接忽略掉了:

>>> BeautifulSoup("

", "lxml")

使用html5lib库解析相同文档会得到不同的结果:

>>> BeautifulSoup("

", "html5lib")

html5lib库没有忽略掉

标签,而是自动补全了标签,还给文档树添加了标签.

使用pyhton内置库解析结果如下:

>>> BeautifulSoup("

", "html.parser")

与lxml 库类似的,Python内置库忽略掉了

标签,与html5lib库不同的是标准库没有尝试创建符合标准的文档格式或将文档片段包含在标签内,与lxml不同的是标准库甚至连标签都没有尝试去添加.
因为文档片段“

”是错误格式,所以以上解析方式都能算作”正确”,html5lib库使用的是HTML5的部分标准,所以最接近”正确”.不过所有解析器的结构都能够被认为是”正常”的.
不同的解析器可能影响代码执行结果,如果在分发给别人的代码中使用了 BeautifulSoup ,那么最好注明使用了哪种解析器,以减少不必要的麻烦.

任重道远

你可能感兴趣的:(Beautiful Soup4学习笔记(六):输出,编译器)