剖析文档
Beautiful Soup使用XML或HTML文档以字符串的方式(或类文件对象)构造。 它剖析文档并在内存中创建通讯的数据结构
如果你的文档格式是非常标准的,解析出来的数据结构正如你的原始文档。但是 如果你的文档有问题,Beautiful Soup会使用heuristics修复可能的结构问题。
剖析 HTML
使用 BeautifulSoup
类剖析HTML文档。 BeautifulSoup
会得出以下一些信息:
- 有些标签可以内嵌 (<BLOCKQUOTE>) ,有些不行 (<P>).
- table和list标签有一个自然的内嵌顺序。例如,<TD> 标签内为 <TR> 标签,而不会相反。
- <SCRIPT> 标签的内容不会被剖析为HTML。
- <META> 标签可以知道文档的编码类型。
这是运行例子:
from BeautifulSoup import BeautifulSoup
html = "<html><p>Para 1<p>Para 2<blockquote>Quote 1<blockquote>Quote 2"
soup = BeautifulSoup(html)
print soup.prettify()
# <html>
# <p>
# Para 1
# </p>
# <p>
# Para 2
# <blockquote>
# Quote 1
# <blockquote>
# Quote 2
# </blockquote>
# </blockquote>
# </p>
# </html>
注意:BeautifulSoup
会智能判断那些需要添加关闭标签的位置,即使原始的文档没有。
也就是说那个文档不是一个有效的HTML,但是它也不是太糟糕。下面是一个比较糟糕的文档。 在一些问题中,它的<FORM>的开始在 <TABLE> 外面,结束在<TABLE>里面。 (这种HTML在一些大公司的页面上也屡见不鲜)
from BeautifulSoup import BeautifulSoup
html = """
<html>
<form>
<table>
<td><input>Row 1 cell 1
<tr><td>Row 2 cell 1
</form>
<td>Row 2 cell 2<br>This</br> sure is a long cell
</body>
</html>"""
Beautiful Soup 也可以处理这个文档:
print BeautifulSoup(html).prettify()
# <html>
# <form>
# <table>
# <td>
# <input />
# Row 1 cell 1
# </td>
# <tr>
# <td>
# Row 2 cell 1
# </td>
# </tr>
# </table>
# </form>
# <td>
# Row 2 cell 2
# <br />
# This
# sure is a long cell
# </td>
# </html>
table的最后一个单元格已经在标签<TABLE>外了;Beautiful Soup 决定关闭<TABLE>标签当它在<FORM>标签哪里关闭了。 写这个文档家伙原本打算使用<FORM>标签扩展到table的结尾,但是Beautiful Soup 肯定不知道这些。即使遇到这样糟糕的情况, Beautiful Soup 仍可以剖析这个不合格文档,使你开业存取所有数据。
剖析 XML
BeautifulSoup
类似浏览器,是个具有启发性的类,可以尽可能的推测HTML文档作者的意图。 但是XML没有固定的标签集合,因此这些启发式的功能没有作用。因此 BeautifulSoup
处理XML不是很好。
使用BeautifulStoneSoup
类剖析XML文档。它是一个 概括的类,没有任何特定的XML方言已经简单的标签内嵌规则。 下面是范例:
from BeautifulSoup import BeautifulStoneSoup
xml = "<doc><tag1>Contents 1<tag2>Contents 2<tag1>Contents 3"
soup = BeautifulStoneSoup(xml)
print soup.prettify()
# <doc>
# <tag1>
# Contents 1
# <tag2>
# Contents 2
# </tag2>
# </tag1>
# <tag1>
# Contents 3
# </tag1>
# </doc>
BeautifulStoneSoup
的一个主要缺点就是它不知道如何处理自结束标签 。 HTML 有固定的自结束标签集合,但是XML取决对应的DTD文件。你可以通过传递selfClosingTags
的参数的名字到 BeautifulStoneSoup
的构造器中,指定自结束标签:
from BeautifulSoup import BeautifulStoneSoup
xml = "<tag>Text 1<selfclosing>Text 2"
print BeautifulStoneSoup(xml).prettify()
# <tag>
# Text 1
# <selfclosing>
# Text 2
# </selfclosing>
# </tag>
print BeautifulStoneSoup(xml, selfClosingTags=['selfclosing']).prettify()
# <tag>
# Text 1
# <selfclosing />
# Text 2
# </tag>
如果它不工作
这里有 一些其他的剖析类 使用与上述两个类不同的智能感应。 你也可以子类化以及定制一个剖析器 使用你自己的智能感应方法。