有时候你要把抓回来的数据进行提取,过大篇幅的html标签,你若使用正则表达式进行匹配的话,显然是低效的,这时使用python的HTMLParser模块会显得非常方便。据说还有个比较好用的解析器叫:Beautiful Soup,这个以后有机会再说吧,现在本渣连实习都找不到,再搞这个东西估计没法生活了。。。。。。

事先说明:我们要解析的html和xhtml的语法是规范的那一种,如果遇到不规范的就gg了,得自己手写正则提取。还有,对于那些转义字符没转义就先不考虑了。。。。。。。

关于HTMLParser与SGMLParser:

网上看很多大牛说HTMLParser对中文字符的提取很不好,推荐使用SGMLParser,但是python的官方文档的Demo是用HTMLParser写的。那就学HTMLParser,反正据说两者是继承关系。

先上文档的Demo:

 #!/usr/bin/env python
#-*-coding:utf-8-*- from HTMLParser import HTMLParser
from htmlentitydefs 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 = unichr(name2codepoint[name])
print "Named ent:",c
#处理转义的数字字符(ACSII)
def handle_charref(self,name):
if name.startswith('x'):
c = unichr(int(name[1:],16)) #十六进制
else:
c = unichr(int(name))
print "Num ent :",c
#匹配HTML头
def handle_decl(self,data):
print "Decl :",data parser = MyHTMLParser() parser.feed('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML4.01//EN"''"http://www.w3.org/TR/html4/strict.dtd">')
#Decl : DOCTYPE HTML PUBLIC "-//W3C//DTD HTML4.01//EN""http://www.w3.org/TR/html4/strict.dtd" 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('<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 parser.feed('<!-- a comment --><!--[if IE 9]>IE-specific content<![endif]-->')
#Comment : a comment
#Comment : [if IE 9]>IE-specific content<![endif] parser.feed('&gt;>>')
#Named ent: >
#Num ent : >
#Num ent : > 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文件中的信息只有3个主要的用途:

  • 提取标题和段落;
  • 提取img的图片,另存为文件;
  • 提取href中的链接

1.提取标题和段落:

 #!/usr/bin/env python
#-*-coding:utf-8-*- from htmlentitydefs import entitydefs
from HTMLParser import HTMLParser class TitleParser(HTMLParser): def __init__(self):
#定义要搜寻的标签
self.handledtags = ['title','p'] #提出标签,理论上可以提取所有标签的内容
self.processing = None
HTMLParser.__init__(self) #继承父类的构造函数 def handle_starttag(self,tag,attrs):
#判断是否在要搜寻的标签内
if tag in self.handledtags:
self.data = ''
self.processing = tag def handle_data(self,data):
if self.processing:
self.data += data def handle_endtag(self,tag):
if tag == self.processing:
print str(tag)+' : '+str(self.data)
self.processing = None #下面两个函数都是对html实体做的转码,没有深究
def handle_entityref(self,name):
if entitydefs.has_key(name):
self.handle_data(entitydefs[name])
else:
self.handle_data('&'+name+';') def handle_charref(self,name):
try:
charnum=int(name)
except ValueError:
return
if charnum<1 or charnum>255:
return
self.handle_data(chr(charnum)) parser = TitleParser()
html1 = """
<html>
<head>
<title> XHTML 与 HTML 4.01 标准没有太多的不同</title>
</head>
<body>
<p>i love you</p>
</body>
</html>
""" html2 = """
<html>
<head>
<title> XHTML 与&quot; HTML 4.01 &quot;标准没有太多的不同</title>
</head>
<body>
<p>i love÷ you&times;</p>
</body>
</html>
"""
parser.feed(html2)

2.提取img的图片,另存为文件

 #!/usr/bin/env python
#-*-coding:utf-8-*- from htmlentitydefs import entitydefs
from HTMLParser import HTMLParser
import urllib
import time class ImgParser(HTMLParser): num = 1 def __init__(self):
#定义要搜寻的标签
self.processing = None
HTMLParser.__init__(self) #继承父类的构造函数
self.addr='' def handle_starttag(self,tag,attrs):
#判断是否在要搜寻的标签内
if tag == 'img':
print 'pic'+str(self.num) + " : " + tag
self.num += 1
for key,value in attrs:
if key == 'src':
self.addr = value
#在类的成员函数中,使用类中的另一个成员函数,前面必须要指定类名
ImgParser.getImage(self) #合法
print key + " : " + value
if key == 'alt':
print key + " : " + value def getImage(self):
u = urllib.urlopen(self.addr)
data = u.read()
filename = self.addr.split('/')[-1]
timestr = time.strftime('%Y%m%d%S',time.localtime(time.time()))
f = open('/home/dzhwen/python文件/Homework/urllib/pic/'+timestr+filename,'wb')
f.write(data)
f.close() parser = ImgParser()
f = urllib.urlopen('http://www.sina.com.cn/') #抓取新浪网上以img标签开头的图片
parser.feed(f.read())

3.提取href中的链接

 #!/usr/bin/env python
#-*-coding:utf-8-*- from htmlentitydefs import entitydefs
from HTMLParser import HTMLParser
import urllib class LinkParser(HTMLParser): def __init__(self):
#定义要搜寻的标签
self.handledtags = ['a'] #提出标签,理论上可以提取所有标签的内容
self.processing = None
self.linkstr = '' #定义链接的标题
self.linkaddr = '' #定义链接的地址
HTMLParser.__init__(self) #继承父类的构造函数 def handle_starttag(self,tag,attrs):
#判断是否在要搜寻的标签内
if tag in self.handledtags:
for name,value in attrs:
if name == 'href':
self.linkaddr = value
self.processing = tag
self.linkstr = '' def handle_data(self,data):
if self.processing:
self.linkstr += data def handle_endtag(self,tag):
if tag == self.processing:
print self.linkstr.decode('utf-8') + ' : ' + self.linkaddr.decode('utf-8')
self.processing = None #下面两个函数都是对html实体做的转码,没有深究
def handle_entityref(self,name):
if entitydefs.has_key(name):
self.handle_data(entitydefs[name])
else:
self.handle_data('&'+name+';') def handle_charref(self,name):
try:
charnum=int(name)
except ValueError:
return
if charnum<1 or charnum>255:
return
self.handle_data(chr(charnum)) parser = LinkParser()
f = urllib.urlopen('http://www.csdn.net/') #解析csdn主页的链接
parser.feed(f.read())

不过很多网站的数据都用js来包装,这样就不能单纯用HTMLParser来解析了,需要用到别的工具,还是回去好好练级吧。。。。

搞到这里,基本的爬虫能掌握思路了,解析来就剩下Beautiful Soup ,Scrapy 和 异步编程还没学(用来进行大幅度的下载和抓取)。。。。。。迫于生活压力,估计没那么快更了,被迫进军java后台了(谁叫外面的世界都是java的天下呢?)唉。。。。。。

解析html与xhtml的神器——HTMLParser与SGMLParser的更多相关文章

  1. HTMLParser-简单HTML和XHTML解析

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

  2. 使用Python中的HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies(二)(转)

    对搜索引擎.文件索引.文档转换.数据检索.站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理.事实上,通过 Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览 ...

  3. Python中的HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies(二)

    对搜索引擎.文件索引.文档转换.数据检索.站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理.事实上,通过 Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览 ...

  4. 将HTML转成XHTML并清除一些无用的标签和属性

    介绍 这是一个能帮你从HTML生成有效XHTML的经典库.它还提供对标签以及属性过滤的支持.你可以指定允许哪些标签和属性可在出现在输出中,而其他的标签过滤掉.你也可以使用这个库清理Microsoft ...

  5. Python3 内建模块 hashlib、itertools、HTMLParser、urllib

    Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制 ...

  6. 精通 Oracle+Python,第 3 部分:数据解析

    进行数据解析的理由不计其数,相关的工具和技巧也同样如此.但是,当您需要用这些数据做一些新的事情时,即使有“合适的”工具可能也是不够的.这一担心对于异类数据源的集成同样存在.用来做这项工作的合适工具迟早 ...

  7. ASP.NET 动态查找数据 并且生成xml文档 同时使用xslt转换为xhtml

    前言 xsl是一门标签解析语言,很适合做动态网页的前台标签 www.bamn.cn 1 首先是aspx页面 添加一个输入框 按钮 还有一个用来显示解析后的xhtml代码的控件 <form id= ...

  8. Python学习笔记(四十)— 内置模块(9)HTMLParser

    摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432002312 ...

  9. Python的Web编程[0] -> Web客户端[1] -> Web 页面解析

     Web页面解析 / Web page parsing 1 HTMLParser解析 下面介绍一种基本的Web页面HTML解析的方式,主要是利用Python自带的html.parser模块进行解析.其 ...

随机推荐

  1. yum与rmp

    清理一切缓存[root@geust02 ~]# yum   clean  all  重建元数据[root@geust02 ~]# yum  makecache 查询vim相关的软件包[root@geu ...

  2. [BUAA_SE_2017]个人阅读作业 + 总结

    个人阅读作业 银弹 银弹是指能让狼人一枪毙命的致命子弹,对于软件工程而言,我觉得是不存在银弹的.每一项软件开发都是极为特殊的,有特定的需求.特定的功能,如果存在银弹能够直击要害解决问题,那么软件的开发 ...

  3. Java多线程之ThreadLocal总结2

    ThreadLocal是什么 早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地 ...

  4. MT【140】是否存在常数$\textbf{C}$

    \(\textbf{天下事有难易乎?为之,则难者亦易矣 不为,则易者亦难矣------<为学>}\) (中国第59届国际数学奥林匹克国家集训队2018.3.20日测试题) 证明:存在常数\ ...

  5. 【刷题】BZOJ 3669 [Noi2014]魔法森林

    Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...

  6. 【刷题】BZOJ 2190 [SDOI2008]仪仗队

    Description 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是 ...

  7. Unity使用C#实现简单Scoket连接及服务端与客户端通讯

    简介: 网络编程是个很有意思的事情,偶然翻出来很久之前刚开始看Socket的时候写的一个实例,贴出来吧 Unity中实现简单的Socket连接,c#中提供了丰富的API,直接上代码. 服务端代码: [ ...

  8. 【poj1743】 Musical Theme

    http://poj.org/problem?id=1743 (题目链接) 题意 给出n个音符的乐谱,求其中不重叠的重复最长连续段,重复连续段的定义为两段音符起伏相同. Solution 论文题,相邻 ...

  9. CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先)

    CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先) 题意分析 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天, ...

  10. vim 折叠的用法

    http://www.cnblogs.com/fakis/archive/2011/04/14/2016213.html 1. 折叠方式 可用选项来设定折叠方式: 可在Vim 配置文件中设置 set ...