用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

 

[python]  view plain copy
  1. #------------------ HTMLParser_stack.py ------------------#  
  2. #-- coding: GBK --  
  3. import HTMLParser,sys,os,string  
  4. html = """<html><head><title>Advice</title></head><body> 
  5. <p>The <a href="http://ietf.org" mce_href="http://ietf.org">IETF admonishes: 
  6. <i>Be strict in what you <b>send</b>.</i></a></p> 
  7. <form> 
  8. <input type=submit >  <input type=text name=start size=4></form> 
  9. </body></html> 
  10. """  
  11.   
  12. tagstack = []  
  13. class ShowStructure(HTMLParser.HTMLParser):  
  14.     def handle_starttag(self, tag, attrs): tagstack.append(tag)  
  15.     def handle_endtag(self, tag): tagstack.pop()  
  16.     def handle_data(self, data):  
  17.         if data.strip():  
  18.             for tag in tagstack: sys.stdout.write('/'+tag)  
  19.             sys.stdout.write(' >> %s/n' % data[:40].strip())  
  20. 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 >> .

 

对于一些网页,可能并没有严格的开始结束标签对,这时,我们可以去忽略一些标签。可以自己写个堆栈来处理这些标签。

 

[python]  view plain copy
  1. #*--------------- TagStack class example -----------------#  
  2. class TagStack:  
  3.     def __init__(self, lst=[]): self.lst = lst  
  4.     def __getitem__(self, pos): return self.lst[pos]  
  5.     def append(self, tag):  
  6.     # Remove every paragraph-level tag if this is one  
  7.     if tag.lower() in ('p','blockquote'):  
  8.         self.lst = [t for t in self.lst  
  9.                 if t not in ('p','blockquote')]  
  10.         self.lst.append(tag)  
  11.     def pop(self, tag):  
  12.         # "Pop" by tag from nearest pos, not only last item  
  13.         self.lst.reverse()  
  14.         try:  
  15.         pos = self.lst.index(tag)  
  16.         except ValueError:  
  17.             raise HTMLParser.HTMLParseError, "Tag not on stack"  
  18.         del self.lst[pos]  
  19.         self.lst.reverse()  
  20. 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的用法。

 

[python]  view plain copy
  1. #------------------ HTMLParser_stack.py ------------------#  
  2. #-- coding: GBK --  
  3. import sgmllib,sys,os,string  
  4. html = """<lala><head><title>Advice</title></head><body> 
  5. <p>The <a href="http://ietf.org" mce_href="http://ietf.org">IETF admonishes: 
  6. <i>Be strict in what you <b>send</b>.</i></a></p> 
  7. <form> 
  8. <input type=submit name='我'> 我 <input type=text name=start size=4></form> 
  9. </body></lala> 
  10. """  
  11.   
  12. os.chdir('d://python')  
  13. f=file('testboard.txt','r')  
  14. contest=f.read()  
  15. tagstack = []  
  16. class ShowStructure(sgmllib.SGMLParser):  
  17.     def handle_starttag(self, tag, method,attrs): tagstack.append(tag)  
  18.     def handle_endtag(self, tag): tagstack.pop()  
  19.     def handle_data(self, data):  
  20.         if data.strip():  
  21.             for tag in tagstack: sys.stdout.write('/'+tag)  
  22.             sys.stdout.write(' >> %s/n' % data[:40].strip())  
  23.               
  24.     def unknown_starttag(self,tag,attrs):  
  25.         print 'start tag:<'+tag+'>'  
  26.     def unknown_endtag(self,tag):  
  27.         print 'end tag:</'+tag+'>'  
  28.     def start_lala(self,attr):  
  29.         print 'lala tag found'  
  30. 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,如需转载请自行联系原博主。


相关文章
|
1月前
|
XML JSON 数据处理
超越JSON:Python结构化数据处理模块全解析
本文深入解析Python中12个核心数据处理模块,涵盖csv、pandas、pickle、shelve、struct、configparser、xml、numpy、array、sqlite3和msgpack,覆盖表格处理、序列化、配置管理、科学计算等六大场景,结合真实案例与决策树,助你高效应对各类数据挑战。(238字)
165 0
|
1月前
|
数据采集 存储 JavaScript
解析Python爬虫中的Cookies和Session管理
Cookies与Session是Python爬虫中实现状态保持的核心。Cookies由服务器发送、客户端存储,用于标识用户;Session则通过唯一ID在服务端记录会话信息。二者协同实现登录模拟与数据持久化。
|
2月前
|
XML 前端开发 C#
C#编程实践:解析HTML文档并执行元素匹配
通过上述步骤,可以在C#中有效地解析HTML文档并执行元素匹配。HtmlAgilityPack提供了一个强大而灵活的工具集,可以处理各种HTML解析任务。
184 19
|
2月前
|
JSON 缓存 开发者
淘宝商品详情接口(item_get)企业级全解析:参数配置、签名机制与 Python 代码实战
本文详解淘宝开放平台taobao.item_get接口对接全流程,涵盖参数配置、MD5签名生成、Python企业级代码实现及高频问题排查,提供可落地的实战方案,助你高效稳定获取商品数据。
|
2月前
|
存储 大数据 Unix
Python生成器 vs 迭代器:从内存到代码的深度解析
在Python中,处理大数据或无限序列时,迭代器与生成器可避免内存溢出。迭代器通过`__iter__`和`__next__`手动实现,控制灵活;生成器用`yield`自动实现,代码简洁、内存高效。生成器适合大文件读取、惰性计算等场景,是性能优化的关键工具。
229 2
|
2月前
|
机器学习/深度学习 文字识别 Java
Python实现PDF图片OCR识别:从原理到实战的全流程解析
本文详解2025年Python实现扫描PDF文本提取的四大OCR方案(Tesseract、EasyOCR、PaddleOCR、OCRmyPDF),涵盖环境配置、图像预处理、核心识别与性能优化,结合财务票据、古籍数字化等实战场景,助力高效构建自动化文档处理系统。
672 0
|
2月前
|
机器学习/深度学习 JSON Java
Java调用Python的5种实用方案:从简单到进阶的全场景解析
在机器学习与大数据融合背景下,Java与Python协同开发成为企业常见需求。本文通过真实案例解析5种主流调用方案,涵盖脚本调用到微服务架构,助力开发者根据业务场景选择最优方案,提升开发效率与系统性能。
726 0
机器学习/深度学习 算法 自动驾驶
484 0
|
2月前
|
算法 安全 数据安全/隐私保护
Python随机数函数全解析:5个核心工具的实战指南
Python的random模块不仅包含基础的随机数生成函数,还提供了如randint()、choice()、shuffle()和sample()等实用工具,适用于游戏开发、密码学、统计模拟等多个领域。本文深入解析这些函数的用法、底层原理及最佳实践,帮助开发者高效利用随机数,提升代码质量与安全性。
599 0
|
2月前
|
数据可视化 Linux iOS开发
Python脚本转EXE文件实战指南:从原理到操作全解析
本教程详解如何将Python脚本打包为EXE文件,涵盖PyInstaller、auto-py-to-exe和cx_Freeze三种工具,包含实战案例与常见问题解决方案,助你轻松发布独立运行的Python程序。
956 2

热门文章

最新文章

推荐镜像

更多