python 解析HTML(附通过例子)

有多种库可以选择,本次调查以下几种

SGMLParser:大概是python2.6—3.0之间支持自带库,其它不自带。使用见http://blog.csdn.net/zhaoyl03/article/details/8631645

http://blog.csdn.net/nwpulei/article/details/7272832

HTMLParser:本次主要使用,支持覆盖较广,但使用功能有限。例子见http://www.cnblogs.com/coser/archive/2012/01/09/2317076.html

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

其它的还有很多种。

 

HTMLParserhttps://docs.python.org/2/library/htmlparser.html

http://blog.csdn.net/tianxicool/article/details/5942523

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):方法,则可以自动读取

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值