转自: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. 分布式资源调度--YARN框架

    YARN产生背景 YARN是Hadoop2.x才有的,所以在介绍YARN之前,我们先看一下MapReduce1.x时所存在的问题: 单点故障 节点压力大 不易扩展 MapReduce1.x时的架构如下 ...

  2. AcCoder Contest-115 D - Christmas

    D - Christmas Time limit : 2sec / Memory limit : 1024MB Score : 400 points Problem Statement In some ...

  3. 数据结构(python语言)目录链接

    第一章 准备工作 课时0:0.数据结构(python语言) 基本概念 算法的代价及度量!!!

  4. 教你如何用Docker快速搭建深度学习环境

    本教程搭建集 Tensorflow.Keras.Coffe.PyTorch 等深度学习框架于一身的环境,及jupyter. 本教程使用nvidia-docker启动实例,通过本教程可以从一个全新的Ub ...

  5. MapReduce 并行编程理论基础

    对于mapreduce这一并行计算模型,一直以来都不是很清楚其具体的执行细节,今天看了学院一位老师的实验指导书,对这一过程有了一个初步的理解,特别是map阶段和reduce阶段,所以做了一份笔记,现在 ...

  6. iOS-plist文件的写读

    NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"xiaoli" ofType:@"plist ...

  7. linux基础优化

    [root@moban oldboy]# for oldboy in `chkconfig --list |grep "3:on" |awk '{print $1}' |grep ...

  8. vue2.0 vue-cli项目中路由之间的参数传递

    1.首先配置路由, import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new R ...

  9. maven中进行go的编译

    maven提供的插件maven-antrun-plugin真是个好东东,使得maven可以利用ant的很多功能. 最近需要实现在maven中实现对go代码的编译,添加如下代码在pom文件中即可. &l ...

  10. 计蒜客16495 Truefriend(fwt)

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; type ...