Beautiful Soup 3

Beautiful Soup 3是上一个发布版本,目前已经停止维护.Beautiful Soup 3库目前已经被几个主要的linux平台添加到源里:

$ apt-get install Python-beautifulsoup

在PyPi中分发的包名字是 BeautifulSoup :

$ easy_install BeautifulSoup

$ pip install BeautifulSoup

或通过 Beautiful Soup 3.2.0源码包 安装

Beautiful Soup 3的在线文档查看 这里 ,当然还有 中文版 ,然后再读本片文档,来对比Beautiful Soup 4中有什新变化.

迁移到BS4

只要一个小变动就能让大部分的Beautiful Soup 3代码使用Beautiful Soup 4的库和方法—-修改 BeautifulSoup 对象的引入方式:

from BeautifulSoup import BeautifulSoup

修改为:

from bs4 import BeautifulSoup
  • 如果代码抛出 ImportError 异常“No module named BeautifulSoup”,原因可能是尝试执行Beautiful Soup 3,但环境中只安装了Beautiful Soup 4库
  • 如果代码跑出 ImportError 异常“No module named bs4”,原因可能是尝试运行Beautiful Soup 4的代码,但环境中只安装了Beautiful Soup 3.

虽然BS4兼容绝大部分BS3的功能,但BS3中的大部分方法已经不推荐使用了,就方法按照 PEP8标准 重新定义了方法名.很多方法都重新定义了方法名,但只有少数几个方法没有向下兼容.

上述内容就是BS3迁移到BS4的注意事项

需要的解析器

Beautiful Soup 3曾使用Python的 SGMLParser 解析器,这个模块在Python3中已经被移除了.Beautiful Soup 4默认使用系统的 html.parser ,也可以使用lxml或html5lib扩展库代替.查看 安装解析器 章节

因为 html.parser 解析器与 SGMLParser 解析器不同,它们在处理格式不正确的文档时也会产生不同结果.通常 html.parser 解析器会抛出异常.所以推荐安装扩展库作为解析器.有时 html.parser 解析出的文档树结构与 SGMLParser 的不同.如果发生这种情况,那么需要升级BS3来处理新的文档树.

方法名的变化

  • renderContents -> encode_contents
  • replaceWith -> replace_with
  • replaceWithChildren -> unwrap
  • findAll -> find_all
  • findAllNext -> find_all_next
  • findAllPrevious -> find_all_previous
  • findNext -> find_next
  • findNextSibling -> find_next_sibling
  • findNextSiblings -> find_next_siblings
  • findParent -> find_parent
  • findParents -> find_parents
  • findPrevious -> find_previous
  • findPreviousSibling -> find_previous_sibling
  • findPreviousSiblings -> find_previous_siblings
  • nextSibling -> next_sibling
  • previousSibling -> previous_sibling

Beautiful Soup构造方法的参数部分也有名字变化:

  • BeautifulSoup(parseOnlyThese=...) -> BeautifulSoup(parse_only=...)
  • BeautifulSoup(fromEncoding=...) -> BeautifulSoup(from_encoding=...)

为了适配Python3,修改了一个方法名:

  • Tag.has_key() -> Tag.has_attr()

修改了一个属性名,让它看起来更专业点:

  • Tag.isSelfClosing -> Tag.is_empty_element

修改了下面3个属性的名字,以免雨Python保留字冲突.这些变动不是向下兼容的,如果在BS3中使用了这些属性,那么在BS4中这些代码无法执行.

  • UnicodeDammit.Unicode -> UnicodeDammit.Unicode_markup``
  • Tag.next -> Tag.next_element
  • Tag.previous -> Tag.previous_element

生成器

将下列生成器按照PEP8标准重新命名,并转换成对象的属性:

  • childGenerator() -> children
  • nextGenerator() -> next_elements
  • nextSiblingGenerator() -> next_siblings
  • previousGenerator() -> previous_elements
  • previousSiblingGenerator() -> previous_siblings
  • recursiveChildGenerator() -> descendants
  • parentGenerator() -> parents

所以迁移到BS4版本时要替换这些代码:

for parent in tag.parentGenerator():
    ...

替换为:

for parent in tag.parents:
    ...

(两种调用方法现在都能使用)

BS3中有的生成器循环结束后会返回 None 然后结束.这是个bug.新版生成器不再返回 None .

BS4中增加了2个新的生成器, .strings 和 stripped_strings . .strings 生成器返回NavigableString对象, .stripped_strings 方法返回去除前后空白的Python的string对象.

XML

BS4中移除了解析XML的 BeautifulStoneSoup 类.如果要解析一段XML文档,使用 BeautifulSoup 构造方法并在第二个参数设置为“xml”.同时 BeautifulSoup 构造方法也不再识别 isHTML 参数.

Beautiful Soup处理XML空标签的方法升级了.旧版本中解析XML时必须指明哪个标签是空标签. 构造方法的 selfClosingTags 参数已经不再使用.新版Beautiful Soup将所有空标签解析为空元素,如果向空元素中添加子节点,那么这个元素就不再是空元素了.

实体

HTML或XML实体都会被解析成Unicode字符,Beautiful Soup 3版本中有很多处理实体的方法,在新版中都被移除了. BeautifulSoup 构造方法也不再接受 smartQuotesToconvertEntities 参数. 编码自动检测 方法依然有 smart_quotes_to 参数,但是默认会将引号转换成Unicode.内容配置项 HTML_ENTITIES , XML_ENTITIESXHTML_ENTITIES 在新版中被移除.因为它们代表的特性已经不再被支持.

如果在输出文档时想把Unicode字符转换成HTML实体,而不是输出成UTF-8编码,那就需要用到 输出格式 的方法.

迁移杂项

Tag.string 属性现在是一个递归操作.如果A标签只包含了一个B标签,那么A标签的.string属性值与B标签的.string属性值相同.

多值属性 比如 class 属性包含一个他们的值的列表,而不是一个字符串.这可能会影响到如何按照CSS类名哦搜索tag.

如果使用 find* 方法时同时传入了 text 参数name 参数 .Beautiful Soup会搜索指定name的tag,并且这个tag的 Tag.string 属性包含text参数的内容.结果中不会包含字符串本身.旧版本中Beautiful Soup会忽略掉tag参数,只搜索text参数.

BeautifulSoup 构造方法不再支持 markupMassage 参数.现在由解析器负责文档的解析正确性.

很少被用到的几个解析器方法在新版中被移除,比如 ICantBelieveItsBeautifulSoupBeautifulSOAP .现在由解析器完全负责如何解释模糊不清的文档标记.

prettify() 方法在新版中返回Unicode字符串,不再返回字节流.

BeautifulSoup3 文档

[1]BeautifulSoup的google讨论组不是很活跃,可能是因为库已经比较完善了吧,但是作者还是会很热心的尽量帮你解决问题的.
[2](1, 2) 文档被解析成树形结构,所以下一步解析过程应该是当前节点的子节点
[3]过滤器只能作为搜索文档的参数,或者说应该叫参数类型更为贴切,原文中用了 filter 因此翻译为过滤器
[4]元素参数,HTML文档中的一个tag节点,不能是文本节点
[5](1, 2, 3, 4, 5) 采用先序遍历方式
[6](1, 2) CSS选择器是一种单独的文档搜索语法, 参考 http://www.w3school.com.cn/css/css_selector_type.asp
[7]原文写的是 html5lib, 译者觉得这是愿文档的一个笔误
[8]wrap含有包装,打包的意思,但是这里的包装不是在外部包装而是将当前tag的内部内容包装在一个tag里.包装原来内容的新tag依然在执行 wrap() 方法的tag内
[9]文档中特殊编码字符被替换成特殊字符(通常是�)的过程是Beautful Soup自动实现的,如果想要多种编码格式的文档被完全转换正确,那么,只好,预先手动处理,统一编码格式
[10](1, 2) 智能引号,常出现在microsoft的word软件中,即在某一段落中按引号出现的顺序每个引号都被自动转换为左引号,或右引号.
"