]> git.phdru.name Git - bookmarks_db.git/blob - parse_html/bkmk_ph_htmlparser.py
0798467386bda9ab993df160f1d4937b1e1802d9
[bookmarks_db.git] / parse_html / bkmk_ph_htmlparser.py
1 """HTML Parser using Pythons' HTMLParser
2
3 This file is a part of Bookmarks database and Internet robot.
4
5 """
6
7 __author__ = "Oleg Broytman <phd@phdru.name>"
8 __copyright__ = "Copyright (C) 1997-2014 PhiloSoft Design"
9 __license__ = "GNU GPL"
10
11 __all__ = ['parse_html']
12
13
14 from HTMLParser import HTMLParseError
15 from m_lib.net.www.html import HTMLParser as _HTMLParser
16
17
18 class HTMLHeadDone(Exception): pass
19
20
21 class HTMLParser(_HTMLParser):
22    def __init__(self, charset=None):
23       _HTMLParser.__init__(self)
24       self.charset = charset
25       self.meta_charset = 0
26       self.title = None
27       self.refresh = None
28       self.icon = None
29
30    def end_head(self):
31       raise HTMLHeadDone()
32
33    def do_meta(self, attrs):
34       http_equiv = ""
35       content = ""
36
37       for attrname, value in attrs:
38          if value:
39             value = value.strip()
40             if attrname == 'http-equiv':
41                http_equiv = value.lower()
42             elif attrname == 'content':
43                content = value
44             elif (attrname == 'charset') and (not self.charset):
45                self.charset = value.lower()
46                self.meta_charset = 1
47
48       if (not self.charset) and (http_equiv == "content-type"):
49          try:
50             # extract charset from "text/html; foo; charset=UTF-8, bar; baz;"
51             self.charset = content.lower().split('charset=')[1].split(';')[0].split(',')[0]
52             self.meta_charset = 1 # Remember that the charset was retrieved from
53                                   # META tag, not from the Content-Type header
54          except IndexError:
55             pass
56
57       if http_equiv == "refresh":
58          self.refresh = content
59
60    def start_title(self, attrs):
61       self.accumulator = ''
62
63    def end_title(self):
64       if not self.title: # use only the first title
65          self.title = self.accumulator
66
67    def do_link(self, attrs):
68       has_icon = False
69       href = None
70
71       for attrname, value in attrs:
72          if value:
73             value = value.strip()
74             if (attrname == 'rel') and (value.lower() in ('icon', 'shortcut icon')):
75                has_icon = True
76             elif attrname == 'href':
77                href = value
78
79       if has_icon:
80          self.icon = href
81
82
83 def parse_html(html_text, charset=None, log=None):
84    parser = HTMLParser(charset)
85
86    try:
87       parser.feed(html_text)
88    except (HTMLParseError, HTMLHeadDone):
89       pass
90
91    try:
92       parser.close()
93    except (HTMLParseError, HTMLHeadDone):
94       pass
95
96    if (parser.title is None) and (parser.refresh is None) and (parser.icon is None):
97       return None
98    return parser