转自:http://www.cnblogs.com/rzhang/archive/2011/12/29/python-html-parsing.html

Python里常用的网页解析库有BeautifulSoup和lxml.html,其中前者可能更知名一点吧,熊猫开始也是使用的BeautifulSoup,但是发现它实在有几个问题绕不过去,因此最后采用的还是lxml: 

1. BeautifulSoup太慢。熊猫原来写的程序是需要提取不定网页里的正文,因此需要对网页进行很多DOM解析工作,经过测试可以认定BS平均比lxml要慢10倍左右。原因应该是libxml2+libxslt的原生C代码比python还是要更快吧 

2. BS依赖python自带的sgmllib,但是这个sgmllib至少有两个问题。首先,它解析“class=我的CSS类”这样的字符串会有问题,参考下面的代码就知道了。

1
2
3
from BeautifulSoup import BeautifulSoup
html = u'<div class=我的CSS类>hello</div>'
print BeautifulSoup(html).find('div')['class']

打印出来的结果是长度为零的字符串,而不是“我的CSS类”。 

不过这个问题可以通过外围代码来解决,只要改写一下sgmllib的attrfind这个查找元素属性的正则就行,可以改成

1
sgmllib.attrfind = re.compile(r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*(\'[^\']*\'|"[^"]*"|[^\s^\'^\"^>]*))?')

这个问题可以说是网页书写不规范造成的,也不能怨sgmllib吧,但是这和BS原来希望能解析格式不好的HTML的宗旨是相违背的。 

但是第二个问题就比较要命了,参看下面的示例代码。

1
2
3
from BeautifulSoup import BeautifulSoup
html = u'<a onclick="if(x>10) alert(x);" href="javascript:void(0)">hello</a>'
print BeautifulSoup(html).find('a').attrs

打印出来的结果是:

1
[(u'onclick', u'if(x>10) alert(x);')]

显然其中的href属性被抛弃了,原因就是sgmllib库在解析属性的时候一旦遇到了>等特殊符号就会结束属性的解析,要解决这个问题,只能修改sgmllib中SGMLParser的parse_starttag代码,找到292行,即k = match.end(0)这一行,添加下面的代码即可: 

1
2
3
4
if k > j:
    match = endbracket.search(rawdata, k+1)
    if not match: return -1
    j = match.start(0)

因此对比起来lxml会好很多,也许在解析某些HTML的时候真的会出问题,但是就现在使用的情况来说还是挺好的。而且lxml的xpath感觉真的很棒,几年前在折腾ASP.NET/Web Service的时候学习过XPath/XSLT之类的东西,但是实用其实挺少的,这次用lxml的xpath,能速度搞定一大堆较繁琐的元素查找,简直太爽了。例如要查找所有有name属性和content属性的meta元素:

1
dom.xpath('.//meta[@name][@content]')

下面是判断元素x是否是元素y的祖节点的代码:

1
x in y.xpath('ancestor-or-self::*')

此外,lxml里还支持string-length、count等XPath 1.0的函数(参见XPath and XSLT with lxml)。不过2.0的函数,如序列操作的函数就不行了,这需要底层libxml2和libxslt库的升级才行。 

当然,lxml也有它自己的问题,那就是多线程方面貌似有重入性问题,如果需要解析大量网页,那只能启动多个进程来试试了。

转:Python网页解析:BeautifulSoup vs lxml.html的更多相关文章

  1. Python网页解析库:用requests-html爬取网页

    Python网页解析库:用requests-html爬取网页 1. 开始 Python 中可以进行网页解析的库有很多,常见的有 BeautifulSoup 和 lxml 等.在网上玩爬虫的文章通常都是 ...

  2. Python网页解析

    续上篇文章,网页抓取到手之后就是解析网页了. 在Python中解析网页的库不少,我最开始使用的是BeautifulSoup,貌似这个也是Python中最知名的HTML解析库.它主要的特点就是容错性很好 ...

  3. Python 网页解析器

    Python 有几种网页解析器? 1. 正则表达式 2.html.parser (Python自动) 3.BeautifulSoup(第三方)(功能比较强大) 是一个HTML/XML的解析器 4.lx ...

  4. 网页解析--BeautifulSoup练习

    # coding = utf-8 # BeautifulSoup 主要功能是解析提取HTML数据 # re lxml bs4 # pip install Beautifulsoup4 # from b ...

  5. ubuntu下的python网页解析库的安装——lxml, Beautiful Soup, pyquery, tesserocr

    lxml 的安装(xpath) pip3 install lxml 可能会缺少以下依赖: sudo apt-get install -y python3-dev build-e ssential li ...

  6. Python爬虫解析htm时lxml的HtmlElement对象获取和设置inner html方法

    Python的lxml是一个相当强悍的解析html.XML的模块,最新版本支持的python版本从2.6到3.6,是写爬虫的必备利器.它基于C语言库libxml2 和 libxslt,进行了Pytho ...

  7. python 之网页解析器

    一.什么是网页解析器 1.网页解析器名词解释 首先让我们来了解下,什么是网页解析器,简单的说就是用来解析html网页的工具,准确的说:它是一个HTML网页信息提取工具,就是从html网页中解析提取出“ ...

  8. 关于爬虫中常见的两个网页解析工具的分析 —— lxml / xpath 与 bs4 / BeautifulSoup

    http://www.cnblogs.com/binye-typing/p/6656595.html 读者可能会奇怪我标题怎么理成这个鬼样子,主要是单单写 lxml 与 bs4 这两个 py 模块名可 ...

  9. 【Python爬虫】BeautifulSoup网页解析库

    BeautifulSoup 网页解析库 阅读目录 初识Beautiful Soup Beautiful Soup库的4种解析器 Beautiful Soup类的基本元素 基本使用 标签选择器 节点操作 ...

随机推荐

  1. 使用fiddler和jmeter进行简单的接口测试。

    初学接口测试,以下内容是记录首次使用fiddler和jmeter进行接口测试的步骤,可能步骤有点繁琐,如果有不对的地方,欢迎大家指正. 准备活动: 1.打开fiddler,打开fiddler以后会自动 ...

  2. 怎样安装PyCharm

    在地址栏输入http://www.jetbrains.com/pycharm/ 打开PyCharm官网 http://idea.lanyus.com/

  3. Python简要标准库(5)

    hashlib Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 基本的生成MD密匙的函数 import hashlib md5 = hashlib.md5() md5.up ...

  4. Windows Server 2008 R2(x64) IIS7+PHP5(FastCGI)环境搭建

    相关软件下载: 1.PHP下载地址: http://windows.php.net/downloads/releases/php-5.4.4-nts-Win32-VC9-x86.zip 如果是win2 ...

  5. TTY锁屏与解锁

    今天在tmux中使用vim时,不小心按了CTRL+S,结果整个vim不能使用了,在网上查到这里会有锁屏的问题,具体如下: 在tmux中,按CTRL+S,锁屏,按CTRL+Q,解锁.与系统的锁屏和解锁是 ...

  6. LeetCode - 67. Add Binary(4ms)

    Given two binary strings, return their sum (also a binary string). The input strings are both non-em ...

  7. 最小生成树(MST)

    原创 今天来说说最小生成树问题,我们知道最小生成树有两种求法,一种是prim算法,另一种是kruskal算法,关于两种算法的定义以及证明,请查看相关资料,这里不多说,理解起来也相当容易,我们来看一个问 ...

  8. lintcode-109-数字三角形

    109-数字三角形 给定一个数字三角形,找到从顶部到底部的最小路径和.每一步可以移动到下面一行的相邻数字上. 注意事项 如果你只用额外空间复杂度O(n)的条件下完成可以获得加分,其中n是数字三角形的总 ...

  9. WCF服务全局异常处理机制

    服务端增加WCF服务全局异常处理机制,任一WCF服务或接口方式出现异常,将统一调用WCF_ExceptionHandler.ProvideFault方法,因此不需要每个方法使用try catch写法. ...

  10. jQuery添加、移除、改变class属性

    jQuery中一般有3个关于改变元素class的函数addClass.removeClass.toggleClass addClass描述: 为每个匹配的元素添加指定的样式类名$('div').add ...