]> git.phdru.name Git - bookmarks_db.git/blob - parse_html/bkmk_ph_htmlparser.py
b90618f1856d37a99bd78e7931421aa67e6d45b3
[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-2023 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
51                 # "text/html; foo; charset=UTF-8, bar; baz;"
52                 self.charset = content.lower().split('charset=')[1].\
53                     split(';')[0].split(',')[0]
54                 # Remember that the charset was retrieved from
55                 # META tag, not from the Content-Type header
56                 self.meta_charset = 1
57             except IndexError:
58                 pass
59
60         if http_equiv == "refresh":
61             self.refresh = content
62
63     def start_title(self, attrs):
64         self.accumulator = ''
65
66     def end_title(self):
67         if not self.title:  # use only the first title
68             self.title = self.accumulator
69
70     def do_link(self, attrs):
71         has_icon = False
72         href = None
73
74         for attrname, value in attrs:
75             if value:
76                 value = value.strip()
77                 if (attrname == 'rel') and (
78                         value.lower() in ('icon', 'shortcut icon')
79                 ):
80                     has_icon = True
81                 elif attrname == 'href':
82                     href = value
83
84         if has_icon:
85             self.icon = href
86
87
88 def parse_html(html_text, charset=None, log=None):
89     parser = HTMLParser(charset)
90
91     try:
92         parser.feed(html_text)
93     except (HTMLParseError, HTMLHeadDone):
94         pass
95
96     try:
97         parser.close()
98     except (HTMLParseError, HTMLHeadDone):
99         pass
100
101     if (parser.title is None) and (parser.refresh is None) \
102             and (parser.icon is None):
103         return None
104     return parser