用python解析html
python中,有三个库可以解析html文本,HTMLParser,sgmllib,htmllib。他们的实现方法不通,但功能差不多。这三个库中 提供解析html的类都是基类,本身并不做具体的工作。他们在发现的元件后(如标签、注释、声名等),会调用相应的函数,这些函数必须重载,因为基类中不 作处理。
比如:
"""<html><head><title>Advice</title></head><body>
<p>The <a href="http://ietf.org">IETF admonishes:
<i>Be strict in what you <b>send</b>.</i></a></p>
<form>
<input type=submit > <input type=text name=start size=4></form>
</body></html>
"""
如果对这个数据做处理,当检测到<html>标签时,对于HTMLParser,会调用handle_starttag函数。
下面具体介绍下几个库
1、HTMLParser
- #------------------ HTMLParser_stack.py ------------------#
- #-- coding: GBK --
- import HTMLParser,sys,os,string
- html = """<html><head><title>Advice</title></head><body>
- <p>The <a href="http://ietf.org" mce_href="http://ietf.org">IETF admonishes:
- <i>Be strict in what you <b>send</b>.</i></a></p>
- <form>
- <input type=submit > <input type=text name=start size=4></form>
- </body></html>
- """
- tagstack = []
- class ShowStructure(HTMLParser.HTMLParser):
- def handle_starttag(self, tag, attrs): tagstack.append(tag)
- def handle_endtag(self, tag): tagstack.pop()
- def handle_data(self, data):
- if data.strip():
- for tag in tagstack: sys.stdout.write('/'+tag)
- sys.stdout.write(' >> %s/n' % data[:40].strip())
- ShowStructure().feed(html)
此函数的输出:
/html/body/p >> The
/html/body/p/a >> IETF admonishes:
/html/body/p/a/i >> Be strict in what you
/html/body/p/a/i/b >> send
/html/body/p/a/i >> .
对于一些网页,可能并没有严格的开始结束标签对,这时,我们可以去忽略一些标签。可以自己写个堆栈来处理这些标签。
- #*--------------- TagStack class example -----------------#
- class TagStack:
- def __init__(self, lst=[]): self.lst = lst
- def __getitem__(self, pos): return self.lst[pos]
- def append(self, tag):
- # Remove every paragraph-level tag if this is one
- if tag.lower() in ('p','blockquote'):
- self.lst = [t for t in self.lst
- if t not in ('p','blockquote')]
- self.lst.append(tag)
- def pop(self, tag):
- # "Pop" by tag from nearest pos, not only last item
- self.lst.reverse()
- try:
- pos = self.lst.index(tag)
- except ValueError:
- raise HTMLParser.HTMLParseError, "Tag not on stack"
- del self.lst[pos]
- self.lst.reverse()
- tagstack = TagStack()
HTMLParser有个bug,就是不能处理中文属性,比如说,如果网页里有这么一段:
<input type=submit value=跳转到>
那么解析到这一行时就会出错。
错误原因还是正则表达式惹的祸。
attrfind = re.compile(
r'/s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(/s*=/s*'
r'(/'[^/']*/'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$/(/)_#=~@]*))?')
attrfind 没有匹配中文字符。
可以更改这个匹配已修正这个错误。sgmllib则不存在这种错误。
2、sgmllib
html格式为sgml格式的一个子集,所以sgml可以处理跟多的东西,下面通过一段代码来示例sgmllib的用法。
- #------------------ HTMLParser_stack.py ------------------#
- #-- coding: GBK --
- import sgmllib,sys,os,string
- html = """<lala><head><title>Advice</title></head><body>
- <p>The <a href="http://ietf.org" mce_href="http://ietf.org">IETF admonishes:
- <i>Be strict in what you <b>send</b>.</i></a></p>
- <form>
- <input type=submit name='我'> 我 <input type=text name=start size=4></form>
- </body></lala>
- """
- os.chdir('d://python')
- f=file('testboard.txt','r')
- contest=f.read()
- tagstack = []
- class ShowStructure(sgmllib.SGMLParser):
- def handle_starttag(self, tag, method,attrs): tagstack.append(tag)
- def handle_endtag(self, tag): tagstack.pop()
- def handle_data(self, data):
- if data.strip():
- for tag in tagstack: sys.stdout.write('/'+tag)
- sys.stdout.write(' >> %s/n' % data[:40].strip())
- def unknown_starttag(self,tag,attrs):
- print 'start tag:<'+tag+'>'
- def unknown_endtag(self,tag):
- print 'end tag:</'+tag+'>'
- def start_lala(self,attr):
- print 'lala tag found'
- ShowStructure().feed(html)
输出:
start tag:<head>
start tag:<title>
/lala >> Advice
end tag:</title>
end tag:</head>
start tag:<body>
start tag:<p>
/lala >> The
start tag:<a>
/lala >> IETF admonishes:
start tag:<i>
/lala >> Be strict in what you
start tag:<b>
/lala >> send
end tag:</b>
/lala >> .
end tag:</i>
end tag:</a>
end tag:</p>
start tag:<form>
start tag:<input>
/lala >> ϒ
start tag:<input>
end tag:</form>
end tag:</body>
end tag:</lala>
和HTMLParser一样,如果要用sgmllib解析html,则要继承sgmllib.SGMLParser类,此类里的函数都是空的,用户需要重载它。这个类提供的功能是在特定情况下调用相应的函数。
比如当发现<html>标签时,如果并没有定义 start_html(self,attr)函数,则会调用unknown_starttag函数,具体怎么处理则更具用户。
sgml的标签是可以自定义的,比如自己定义了一个start_lala函数,则就会处理<lala>标签。
有 个地方要说明下,如果定义了start_tagname函数,有定义了handle_starttag函数,则函数只会运行 handle_starttag函数,start_tagname为空函数都没有问题,如果没有定义handle_starttag函数,则遇 到<tagname>标签时,会运行start_tagname函数。如果没有定义tagname的start函数,则此标签为未知标签,调 用unknown_starttag函数
用python解析html的更多相关文章
- 使用Python解析JSON数据
使用Python解析百度API返回的JSON格式的数据 # coding:utf-8 # !/usr/bin/env python import matplotlib.pyplot as plt fr ...
- 使用Python解析JSON数据的基本方法
这篇文章主要介绍了使用Python解析JSON数据的基本方法,是Python入门学习中的基础知识,需要的朋友可以参考下: ----------------------------------- ...
- python解析robot framework的output.xml,并生成html
一.背景 Jenkins自动构建RF脚本,生成的RF特有HTML报告不能正常打开. 需求:用Python解析测试报告的xml数据,放在普通HTML文件中打开 二.output.xml数据 三.用pyh ...
- python 解析json loads dumps
认识 引用模块 重要函数 案例 排序 缩进参数 压缩 参考 认识 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于JavaScript(Standa ...
- Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试
摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...
- python 解析XML python模块xml.dom解析xml实例代码
分享下python中使用模块xml.dom解析xml文件的实例代码,学习下python解析xml文件的方法. 原文转自:http://www.jbxue.com/article/16587.html ...
- python解析xml模块封装代码
在python中解析xml文件的模块用法,以及对模块封装的方法.原文转自:http://www.jbxue.com/article/16586.html 有如下的xml文件:<?xml vers ...
- python解析xml之lxml
虽然python解析xml的库很多,但是,由于lxml在底层是用C语言实现的,所以lxml在速度上有明显优势.除了速度上的优势,lxml在使用方面,易用性也非常好.这里将以下面的xml数据为例,介绍l ...
- Python解析生成XML-ElementTree VS minidom
OS:Windows 7 关键字:Python3.4,XML,ElementTree,minidom 本文介绍用Python解析生成以下XML: <Persons> <Person& ...
- python解析xml
python解析xml import xml.dom.minidom as minidom dom = minidom.parse("aa.xml") root = dom.get ...
随机推荐
- 2014年去哪儿网笔试题--有两个文件context.txt和words.conf,请尝试将他们合并成为一段文字,并打印出来。
有两个文件context.txt和words.conf,请尝试将他们合并成为一段文字,并打印出来. 这两个文件内容如下: context.txt “并不是每个人都需要$(qunar)自己的粮食,$(f ...
- beini破解无线
软件介绍 当你的笔记本有无线网卡却不能上网的时刻,也许你会很焦急. 又或许你的隔壁就有无线网络可以接的时刻,但你却由于米有密码而不能上网.下面我将简介一款可以令你惊讶的软件,奶瓶 有了奶瓶以上疑问都可 ...
- 测试横竖屏切换时activity 的生命周期
对于这个面试题,相信大家都见过,网上给出的答案是: 1.不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次 2.设 ...
- DevExpress ASP.NET 使用经验谈(7)-ASPxTreeList控件使用
这一节,将介绍ASPxTreeList控件的使用,首先,我们增加一个标准地址库表AddressGB, 建表语句如下: CREATE TABLE [dbo].[AddressGB]( [Code] [v ...
- js 效果样式大全
设置 滑动图片背景模糊度 <style type='text/css'>/*透明20%*/.opacity-20 {filter:alpha(opacity=20); /*支持IE浏览器的 ...
- Java排序之排序大综合
一.最近写了一些排序,于是和和大家分享一下:(默认都是从小到大排序) 二.冒泡排序 1.什么是冒泡排序:原理是临近的两个数比较大小,将较大的数往后移,这样遍历一趟数组以后,最大的数就排在的最后面(时间 ...
- Vmware中Ubuntu挂ISO到虚拟光驱
Ubuntu 下挂ISO到虚拟光驱的方法 https://i.cnblogs.com/EditPosts.aspx?opt=1 如果要ubuntu找到rpm软件包,需要把iso挂载到/media/cd ...
- OpenCV配置使用版
在VS2010环境中应用Opencv,网上找到了很多配置方法,但大多都是老版本的,很多新手面对最新版本的Opencv无从下手,就给新手童鞋写了这么一篇超级详细的配置攻略,贴上来共享.要强调一点的就是, ...
- mina教程
关于mina介绍这里不做阐述..... 我们先做一个关于mina的helloworld 首先先下载mina包:http://mina.apache.org/ (如果你已经下载,此步骤忽略) 下载下来以 ...
- win7安装 Apache2.2 PHP5.3 MySQL5.6
. APACHE2.2 经典参考资料 http://blog.csdn.net/yousuosi/article/details/9859507 官方下载地址 http://mirror.bi ...