转自: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. Qt 编译时遇到 error: [debug/qrc_music.cpp] Error 1

    第一种方式,清理编译文件 把Qdebug release 文件件都删除, 删除makefile 文件 尝试重新编译 以上是网上寻找的结果 以下是我的解决方法 如果还抱错,请检查qrc文件是否存在异常 ...

  2. fiddler显示出服务器IP方法

    fiddler的配置中是看不到服务器的IP的 1.打开进入fiddler界面,按快捷键ctrl+r 或者按照图中点击,进入customrules.js文件里. 2.在customrules.js文件里 ...

  3. K8s集群内热改代码

    1.登录到k8s master服务器 $ ssh developer@XXX.XXX.X.XXX(IP地址) 2.查看服务容器所在的节点(以xx-server为例) $ kubectl get pod ...

  4. 09-Mysql数据库----外键的变种

    本节重点: 如何找出两张表之间的关系 表的三种关系 一.介绍 因为有foreign key的约束,使得两张表形成了三种了关系: 多对一 多对多 一对一 二.重点理解如果找出两张表之间的关系 分析步骤: ...

  5. nodeJs 调试异步程序追踪异步报错

    DeprecationWarning: Calling an asynchronous function without callback is deprecated. 翻译: 不建议在不回调的情况下 ...

  6. chromium源码阅读

    linux下chromium的入口函数在文件:src/chrome/app/chrome_exe_main_aura.cc 中 int main(int argc, const char** argv ...

  7. 获取JavaScript对象的方法

    写定义一个对象,如var a = new Array(),debugger,然后执行F12控制台的开发者模式下,进入断点,断点里面 会显示所有的方法的. var a = new Array(); de ...

  8. GET传值

    发送页: <form id="form1" runat="server"> <div> <asp:TextBox ID=</ ...

  9. P3539 [POI2012]ROZ-Fibonacci Representation

    题目描述 The Fibonacci sequence is a sequence of integers, called Fibonacci numbers, defined as follows: ...

  10. linq.js的用法

    linq.js 详细介绍 linq.js 是一个 JavaScript 实现的 LINQ. 主要特性: 实现所有 .NET 4.0 的方法 complete lazy evaluation full ...