您的位置:首页 > 编程语言 > Python开发

python 解析HTML(附通过例子)

2014-04-10 01:16 274 查看
有多种库可以选择,本次调查以下几种

SGMLParser:大概是python2.6—3.0之间支持自带库,其它不自带。使用见/article/8440066.html

/article/2795077.html

HTMLParser:本次主要使用,支持覆盖较广,但使用功能有限。例子见/article/5038510.html

BeautifulSoup:据说比较好的第三方库,没有使用,BeautifulStoneSoup还可以处理XML。见http://rsj217.diandian.com/post/2012-11-01/40041235132

其它的还有很多种。

HTMLParser:https://docs.python.org/2/library/htmlparser.html

/article/11063009.html

class HTMLParser.HTMLParser

使用 HTMLParser 的实例,填充 HTML 数据,并在开始和结束标记间调用函数。 HTMLParser 类意味着重载。

和 htmllib 的分析器不同, this parser 并不检测和开始标记对应的结束标记 or call the end-tag handler for elements which are close implicitly by closing an outer element.

这里还有一个例外情况:

exception HTMLParser.HTMLParserError

当分析遇到 Error 时 HTMLParser 会抛出异常。该异常提供三个属性: msg , lineno and offset 。

HTMLParser 实例有如下的方法:

HTMLParser.reset()

重置实例 . 所有未处理的数据都会丢失。在初始化时自动调用。

HTMLParser.feed(data)

给分析器喂食。在由完整元素构成的情况下工作;不完整数据情况下,会进行缓冲知道更多数据加进来或者 close() 被调用。

HTMLParser.close()

处理所有缓冲数据。这个方法可以被派生类重定义,以便在输入结束后处理额外的事情,重定义的版本也要调用 HTMLParser 基类的 close() 方法。

HTMLParser.getpos()

返回当前行数和列数

HTMLParser.get_starttag_text()

返回最近打开过得开始标记处的文本。通常不会用到, but may be useful in dealing with HTML “as deployed” or for re-generating input with minimal changes (whitespace between attributes can be preserved, etc.).

HTMLParser.handle_starttag(tag, attrs)

该方法用来处理一个标记的开始。通常被派生类重载;基类的实例什么都不做。

tag 参数是 tag 的名字的小写化。 attrs 参数是一个 list ,由 (name, value) 组成,反映了 <> 里面的属性。 name 会被翻译成小写字母,在 value 中的引号也被移除了,字符实体引用也会被替换。例如,有个tag<A HREF=”http://www.cwi.nl/”>,那么使用该方法就该这么做:
handle_starttag(’a’, [(’href’, ’http://www.cwi.nl/’)])

Changed in version 2.6: 来自 htmlentitydefs 的所有实体引用都被属性值替换。

HTMLParser.handle_startendtag(tag, attrs)

和 handle_starttag() 类似,用来处理 XHTML 风格的 空标签( <a .../> )。可能被子类重载, which require this particular lexical information; 默认的实现只是简单的调用 handle_starttag() 和 handle_endtag()

HTMLParser.handle_endtag(tag)

该方法用来处理元素结束标记。可以被派生类重载;基类什么也不做。 tag 参数是 tag 的 name 转化来的小写字母。

HTMLParser.handle_data(data)

该方法用来处理随机的数据。可以被派生类重载;基类什么也不做。

HTMLParser.handle_charref(name)

处理 &#ref 格式的字符引用。可以被派生类重载;基类什么也不做。

HTMLParser.handle_entityref(name)

处理一般的 &name 格式的实体引用。 name 是一个一般的实体引用。可以被派生类重载;基类什么也不做。

HTMLParser.handle_comment(data)

处理遇到注释的情况。注释参数为在——和——之间的字符串文本,而不是分隔符自身。例如 <!--text--> ,该方法将调用‘ text ’。可以被派生类重载;基类什么也不做。

HTMLParser.handle_decl(decl)

当分析器遇到 SGML 声明时调用此方法。 decl 参数是 <!...> 标记里的整个内容。可以被派生类重载;基类什么也不做。

HTMLParser.handle_pi(data)

处理命令, data 参数包含整个的处理命令。例如 <?proc color=’red’> ,该方法应写成 handle_pi(”proc color=’red’”). 可以被派生类重载;基类什么也不做。

我的例子:

from HTMLParser import HTMLParser

class MyHTMLParser(HTMLParser):

def __init__(self):

HTMLParser.__init__(self)

self.text = ""

self.links = ""

self.items = []

self.flag1 = False

self.flag2 = False

self.flag3 = False

def handle_starttag(self, tag, attrs):

print "Start tag %s" % tag

if tag == "div":

for (variable, value) in attrs:

if variable == "class":

print "find %s" % value

if value == "descr-left":

print "---------------find %s" % value

self.flag1 = True

if value == "descr-right":

print "---------------find %s" % value

self.flag2 = True

if tag == "a" and self.flag1 == True:

print "Start tag2 %s" % tag

if len(attrs) == 0: pass

else:

for (variable, value) in attrs:

if variable == "href":

self.links = value

if tag == "h4" and self.flag2 == True:

for (variable, value) in attrs:

if variable == "class":

print "find %s" % value

if value == "curr-tit":

print "---------------find %s" % value

self.flag3 = True

def handle_data(self, data):

if self.flag3 == True:

self.text = data

print "---------------find data %s" % data

# if self.flag1 == True:

self.items.append((self.text, self.links))

def handle_entityref(self , name):

if entitydefs.has_key(name):

self.handle_data(name)

else :

self.handle_data("&"+name )

def handle_endtag(self, tag):

if tag == 'div' and self.flag1 == True:

self.flag1 = False

if tag == 'div' and self.flag2 == True:

self.flag2 = False

if tag == 'h4' and self.flag3 == True:

self.flag3 = False

def getItems(self):

return self.items

if __name__=="__main__":

html = "D:\App781286.html"

file = open(html)

try:

text = file.read()

finally:

file.close()

hp = MyHTMLParser()

hp.feed(text)

hp.close()

items = hp.getItems()

for text, links in items :

print text , links

print(hp.getItems())

f = open('D:\download.txt', 'a')

for text, links in items :

f.write("%s : %s \n" % (text, links))

f.close()

注1:如果想处理多个节点的树级结构可以采用flag,见上程序

注2:如上所说该类只是在开始和结束标记然后调用函数,如果想要获取<h4 class="curr-tit">Nokia X计算器</h4>

中“Nokia X计算器”,则只需要在def handle_starttag(self, tag, attrs):和def handle_endtag(self, tag):中标记flag,

然后重写def handle_data(self, data):方法,则可以自动读取
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: