Html / XHtml 解析 - Parsing Html and XHtml
Html / XHtml 解析 - Parsing Html and XHtml
HTMLParser 模块
通过 HTMLParser 模块来解析 html 文件通常的做法是, 建立一个 HTMLParser 子类,
然后子类中实现处理的标签(<.>)的方法, 其实现是通过 '重写' 父类(HTMLParser)的
handle_starttag(), handle_data(), handle_endtag() 等方法. 例子,
解析 htmlsample.html 中 <head> 标签,
<-- htmlsample.html --> -> 文件内容,
'
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>
'
from html.parser import HTMLParser
class ParsingHeadT(HTMLParser):
def __init__(self):
self.headtag =''
self.parsesemaphore = False
HTMLParser.__init__(self) def handle_starttag(self, tag, attrs): # enable semaphore
if tag == 'head':
self.parsesemaphore = True def handle_data(self, data): # tag process as requirement
if self.parsesemaphore:
self.headtag = data def handle_endtag(self, tag):
if tag == 'head':
self.parsesemaphore = False def getheadtag(self):
return self.headtag if __name__ == "__main__":
with open('htmlsample.html') as FH:
pht = ParsingHeadT()
pht.feed(FH.read()) # HTMLParser will invoke the replaced methods
# handle_starttag, handle_data and handle_endtag
print("Head Tag : %s" % pht.getheadtag()) output,
Head Tag : 404 Not Found 上例是一个简单完成的 html 文本, 然而在实际生产中是有一些实现情况要考虑和处理的,
比如 html 中的特殊字符 © (copyright 符号), &(& 逻辑与符号) 等,
对于这种情况, 之前的做法是需要重写父类的 handle_entityref() 来处理,
HTMLParser.handle_entityref(name)¶
This method is called to process a named character reference of the form
&name; (e.g. >), where name is a general entity reference (e.g. 'gt').
This method is never called if convert_charrefs is True. 字符转换 也是一种需要注意的情况, 比如 十进制 decimal 和 十六进制 hexadecimal 字符的转换.
HTMLParser.handle_charref(name)
This method is called to process decimal and hexadecimal numeric character
references of the form &#NNN; and &#xNNN;. For example, the decimal equivalent
for > is >, whereas the hexadecimal is > in this case the method
will receive '' or 'x3E'. This method is never called if convert_charrefs is True. Note,
幸运的是,以上情况在 python 3 已经能很好得帮我们处理了. 还是使用上例, 现在我们在 htmlsample.html
<head> tag 中加入一些特殊字符来看看.
<-- htmlsample.html -->
<html>
<head><title>> > 404 © Not > Found & </title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html> 上例 Output,
Head Tag : > > 404 © Not > Found &
从运行结果可以看出, 在 python 3 中上例能够很好的处理特殊字符的情况. 然而, 在 html 的代码中存在一类 '非对称'的标签, 如 <p>, <li> 等, 当我们试图使用上面的例子
去处理这类非对称标签的时候发现, 这类标签并不能被上例正确解析. 这时我们需要扩展上例的 code 使
其能够正确解析这些'非对称'标签.
先扩展一下儿 htmlsample.html, 以 <li> 标签为例,
<-- htmlsample.html -->
<html>
<head><title>> > 404 © Not > Found &</title>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.12.2</center>
<ul>
<li> First Reason
<li> Second Reason
</body>
</html> htmlsample.html 文件是可以被浏览器渲染的, 然而 htmlsample.html 中 <head> 和 <ul> 标签
没有对应的结束 tag, <li> 为非对称的 tag. 现在来向之前的例子添加一些逻辑来处理这些问题. 例,
from html.parser import HTMLParser
class Parser(HTMLParser):
def __init__(self):
self.taglevels = [] # track anchor
self.tags =['head','ul','li']
self.parsesemaphore = False
self.data = ''
HTMLParser.__init__(self) def handle_starttag(self, tag, attrs): # enable semaphore
if len(self.taglevels) and self.taglevels[-1] == tag:
self.handle_endtag(tag)
self.taglevels.append(tag) if tag in self.tags:
self.parsesemaphore = True def handle_data(self, data): # tag process as requirement
if self.parsesemaphore:
self.data += data def handle_endtag(self, tag):
self.parsesemaphore = False def gettag(self):
return self.data if __name__ == "__main__":
with open('htmlsample.html') as FH:
pht = Parser()
pht.feed(FH.read()) # HTMLParser will invoke the replaced methods
# handle_starttag, handle_data and handle_endtag
print("Head Tag : %s" % pht.gettag()) Output,
Head Tag : > > 404 © Not > Found &
First Reason
Second Reason Reference,
https://docs.python.org/3.6/library/html.parser.html?highlight=htmlparse#html.parser.HTMLParser.handle_entityref Appendix,
The example given by python Doc,
from html.parser import HTMLParser
from html.entities import name2codepoint class MyHTMLParser(HTMLParser):
def handle_starttag(self, tag, attrs):
print("Start tag:", tag)
for attr in attrs:
print(" attr:", attr) def handle_endtag(self, tag):
print("End tag :", tag) def handle_data(self, data):
print("Data :", data) def handle_comment(self, data):
print("Comment :", data) def handle_entityref(self, name):
c = chr(name2codepoint[name])
print("Named ent:", c) def handle_charref(self, name):
if name.startswith('x'):
c = chr(int(name[1:], 16))
else:
c = chr(int(name))
print("Num ent :", c) def handle_decl(self, data):
print("Decl :", data) parser = MyHTMLParser() Output,
Parsing a doctype: # >>> parser.feed('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
... '"http://www.w3.org/TR/html4/strict.dtd">')
Decl : DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"
Parsing an element with a few attributes and a title: # >>> parser.feed('<img src="python-logo.png" alt="The Python logo">')
Start tag: img
attr: ('src', 'python-logo.png')
attr: ('alt', 'The Python logo') # >>> parser.feed('<h1>Python</h1>')
Start tag: h1
Data : Python
End tag : h1
The content of script and style elements is returned as is, without further parsing: # >>> parser.feed('<style type="text/css">#python { color: green }</style>')
Start tag: style
attr: ('type', 'text/css')
Data : #python { color: green }
End tag : style # >>> parser.feed('<script type="text/javascript">'
... 'alert("<strong>hello!</strong>");</script>')
Start tag: script
attr: ('type', 'text/javascript')
Data : alert("<strong>hello!</strong>");
End tag : script
Parsing comments: # >>> parser.feed('<!-- a comment -->'
... '<!--[if IE 9]>IE-specific content<![endif]-->')
Comment : a comment
Comment : [if IE 9]>IE-specific content<![endif]
Parsing named and numeric character references and converting them to the correct
char (note: these 3 references are all equivalent to '>'): # >>> parser.feed('>>>')
Named ent: >
Num ent : >
Num ent : >
Feeding incomplete chunks to feed() works, but handle_data() might be called more
than once (unless convert_charrefs is set to True): # >>> for chunk in ['<sp', 'an>buff', 'ered ', 'text</s', 'pan>']:
... parser.feed(chunk)
Start tag: span
Data : buff
Data : ered
Data : text
End tag : span
Parsing invalid HTML (e.g. unquoted attributes) also works: # >>> parser.feed('<p><a class=link href=#main>tag soup</p ></a>')
Start tag: p
Start tag: a
attr: ('class', 'link')
attr: ('href', '#main')
Data : tag soup
End tag : p
End tag : a
Html / XHtml 解析 - Parsing Html and XHtml的更多相关文章
- python模块介绍- HTMLParser 简单的HTML和XHTML解析器
python模块介绍- HTMLParser 简单的HTML和XHTML解析器 2013-09-11 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq ...
- HTMLParser-简单HTML和XHTML解析
使用HTMLParser模块解析HTML页面 HTMLParser是python用来解析html和xhtml文件格式的模块.它可以分析出html里面的标签.数据等等,是一种处理html的简便途径.HT ...
- XHTML 结构化:使用 XHTML 重构网站
http://www.w3school.com.cn/xhtml/xhtml_structural_01.asp 我们曾经为本节撰写的标题是:"XHTML : 简单的规则,容易的方针.&qu ...
- XHTML 结构化:使用 XHTML 重构网站 分类: C1_HTML/JS/JQUERY 2014-07-31 15:58 249人阅读 评论(0) 收藏
http://www.w3school.com.cn/xhtml/xhtml_structural_01.asp 我们曾经为本节撰写的标题是:"XHTML : 简单的规则,容易的方针.&qu ...
- Sharepoint的网页(Page),网页解析(Parsing)与解析安全处理(Security)
转:http://www.chawenti.com/articles/8592.html Microsoft SharePoint Foundation 中主要有两种类型的页面,分别是应用程序页(Ap ...
- 解析html与xhtml的神器——HTMLParser与SGMLParser
有时候你要把抓回来的数据进行提取,过大篇幅的html标签,你若使用正则表达式进行匹配的话,显然是低效的,这时使用python的HTMLParser模块会显得非常方便.据说还有个比较好用的解析器叫:Be ...
- XHTML代码规则&手工html转换xhtml
XHTML规则 XHTML是XML得一个应用,它遵守XML得规范和要求.从技术角度上讲.这些语法规则是由XML规范定义的. XML文档必须遵守的规则使得生成工具以解析文档变得更容易.这些规则也使得XM ...
- HTML和XHTML区别
HTML和XHTML 可扩展超文本标记语言XHTML(eXtensible HyperText Markup Language)是将超文本标记语言HTML(HyperText Markup Langu ...
- 1; XHTML 基本知识
万维网是我们这个时代最重要的信息传播手段.几乎任何人都可以创建自己的网站,然后把它发布在因特网上.一些网页属于企业,提供销售服务:另一些网页属于个人,用来分享信息.你可以自己决定网页的内容和风格.所有 ...
随机推荐
- 【Think In Java笔记】第1章 对象导论
1. 对象导论 OOP 面向对象编程 C.Basic等语言所在的抽象仍要求在解决问题时基于计算机的解决,而不是基于所解决问题的结构来考虑. 要建立起问题空间的元素和解空间的对象之间一一映射的关系 万物 ...
- 哪些工具可以提升PHP开发效率
本文就我自己在开发过程中的一点经验,谈谈如何利用工具来提升开发工作的编码效率, IDE(phpstorm 收费) 一个好的IDE真的可以给开发人员节省大量的时间,我从最开始使用editplus 到su ...
- UIBPlayer (视频播放)demo分享
本文出自APICloud官方论坛 UIBPlayer 封装了百度云播放器 SDK.本模块带有UI方案,打开后为一个具有完整功能的播放器界面.百度云播放器突破 Android.iOS 平台对视频格式的限 ...
- 点分治 (等级排) codeforces 321C
Now Fox Ciel becomes a commander of Tree Land. Tree Land, like its name said, has n cities connected ...
- 自己动手搭环境—unit 1.1、Struts2环境搭建
在手动配置action的基础上引入struts2-convention-plugin-2.x.x.jar以支持action的注解支持 修改的地方主要在struts.xml中 <?xml vers ...
- VirtualBox扩充磁盘&清空安装包
1.virtual box 扩充磁盘空间 D:\VirtualBox\VBoxManage.exe modifyhd "E:\virtual box\daisyyun\daisyyun.vd ...
- Governing sand 贪心
题目链接:https://ac.nowcoder.com/acm/contest/887/C 题目描述 The Wow village is often hit by wind and sand,th ...
- Spring MVC中的拦截器Interceptor
谈谈spring中的拦截器 在web开发中,拦截器是经常用到的功能.它可以帮我们验证是否登陆.预先设置数据以及统计方法的执行效率等等.今天就来详细的谈一下spring中的拦截器.spring中拦截器主 ...
- 编写python程序读入1到100之间的整数,然后计算每个数出现的次数,输入0表示结束输人,输入数据不包括0。如果数出现的大现如果大于1,输出时使用复数times
#-*- coding:UTF-8 -*- #环境:python3 print("Enter the numbers between 1 and 100:") enterList= ...
- 看透Spring MVC:源代码分析与实践 (Web开发技术丛书)
第一篇 网站基础知识 第1章 网站架构及其演变过程2 1.1 软件的三大类型2 1.2 基础的结构并不简单3 1.3 架构演变的起点5 1.4 海量数据的解决方案5 1.4.1 缓存和页面静态化5 1 ...