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 中的特殊字符 &copy (copyright 符号), &amp(& 逻辑与符号) 等,
对于这种情况, 之前的做法是需要重写父类的 handle_entityref() 来处理,
HTMLParser.handle_entityref(name)¶
This method is called to process a named character reference of the form
&name; (e.g. &gt;), 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 &gt; is &#62;, 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>&#62 &#x3E 404 &copy Not &gt 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>&#62 &#x3E 404 &copy Not &gt 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('&gt;>>')
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的更多相关文章

  1. python模块介绍- HTMLParser 简单的HTML和XHTML解析器

    python模块介绍- HTMLParser 简单的HTML和XHTML解析器 2013-09-11 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq ...

  2. HTMLParser-简单HTML和XHTML解析

    使用HTMLParser模块解析HTML页面 HTMLParser是python用来解析html和xhtml文件格式的模块.它可以分析出html里面的标签.数据等等,是一种处理html的简便途径.HT ...

  3. XHTML 结构化:使用 XHTML 重构网站

    http://www.w3school.com.cn/xhtml/xhtml_structural_01.asp 我们曾经为本节撰写的标题是:"XHTML : 简单的规则,容易的方针.&qu ...

  4. 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 ...

  5. Sharepoint的网页(Page),网页解析(Parsing)与解析安全处理(Security)

    转:http://www.chawenti.com/articles/8592.html Microsoft SharePoint Foundation 中主要有两种类型的页面,分别是应用程序页(Ap ...

  6. 解析html与xhtml的神器——HTMLParser与SGMLParser

    有时候你要把抓回来的数据进行提取,过大篇幅的html标签,你若使用正则表达式进行匹配的话,显然是低效的,这时使用python的HTMLParser模块会显得非常方便.据说还有个比较好用的解析器叫:Be ...

  7. XHTML代码规则&手工html转换xhtml

    XHTML规则 XHTML是XML得一个应用,它遵守XML得规范和要求.从技术角度上讲.这些语法规则是由XML规范定义的. XML文档必须遵守的规则使得生成工具以解析文档变得更容易.这些规则也使得XM ...

  8. HTML和XHTML区别

    HTML和XHTML 可扩展超文本标记语言XHTML(eXtensible HyperText Markup Language)是将超文本标记语言HTML(HyperText Markup Langu ...

  9. 1; XHTML 基本知识

    万维网是我们这个时代最重要的信息传播手段.几乎任何人都可以创建自己的网站,然后把它发布在因特网上.一些网页属于企业,提供销售服务:另一些网页属于个人,用来分享信息.你可以自己决定网页的内容和风格.所有 ...

随机推荐

  1. 【Think In Java笔记】第1章 对象导论

    1. 对象导论 OOP 面向对象编程 C.Basic等语言所在的抽象仍要求在解决问题时基于计算机的解决,而不是基于所解决问题的结构来考虑. 要建立起问题空间的元素和解空间的对象之间一一映射的关系 万物 ...

  2. 哪些工具可以提升PHP开发效率

    本文就我自己在开发过程中的一点经验,谈谈如何利用工具来提升开发工作的编码效率, IDE(phpstorm 收费) 一个好的IDE真的可以给开发人员节省大量的时间,我从最开始使用editplus 到su ...

  3. UIBPlayer (视频播放)demo分享

    本文出自APICloud官方论坛 UIBPlayer 封装了百度云播放器 SDK.本模块带有UI方案,打开后为一个具有完整功能的播放器界面.百度云播放器突破 Android.iOS 平台对视频格式的限 ...

  4. 点分治 (等级排) codeforces 321C

    Now Fox Ciel becomes a commander of Tree Land. Tree Land, like its name said, has n cities connected ...

  5. 自己动手搭环境—unit 1.1、Struts2环境搭建

    在手动配置action的基础上引入struts2-convention-plugin-2.x.x.jar以支持action的注解支持 修改的地方主要在struts.xml中 <?xml vers ...

  6. VirtualBox扩充磁盘&清空安装包

    1.virtual box 扩充磁盘空间 D:\VirtualBox\VBoxManage.exe modifyhd "E:\virtual box\daisyyun\daisyyun.vd ...

  7. Governing sand 贪心

    题目链接:https://ac.nowcoder.com/acm/contest/887/C 题目描述 The Wow village is often hit by wind and sand,th ...

  8. Spring MVC中的拦截器Interceptor

    谈谈spring中的拦截器 在web开发中,拦截器是经常用到的功能.它可以帮我们验证是否登陆.预先设置数据以及统计方法的执行效率等等.今天就来详细的谈一下spring中的拦截器.spring中拦截器主 ...

  9. 编写python程序读入1到100之间的整数,然后计算每个数出现的次数,输入0表示结束输人,输入数据不包括0。如果数出现的大现如果大于1,输出时使用复数times

    #-*- coding:UTF-8 -*- #环境:python3 print("Enter the numbers between 1 and 100:") enterList= ...

  10. 看透Spring MVC:源代码分析与实践 (Web开发技术丛书)

    第一篇 网站基础知识 第1章 网站架构及其演变过程2 1.1 软件的三大类型2 1.2 基础的结构并不简单3 1.3 架构演变的起点5 1.4 海量数据的解决方案5 1.4.1 缓存和页面静态化5 1 ...