]> git.phdru.name Git - bookmarks_db.git/blob - parse_html/bkmk_ph_htmlparser.py
Fix(parse_html): Do not parse empty strings
[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 try:
15     from HTMLParser import HTMLParseError
16 except ImportError:
17     class HTMLParseError(Exception): pass
18 from m_lib.net.www.html import HTMLParser as _HTMLParser
19
20
21 class HTMLHeadDone(Exception): pass
22
23
24 class HTMLParser(_HTMLParser):
25     def __init__(self, charset=None):
26         _HTMLParser.__init__(self)
27         self.charset = charset
28         self.meta_charset = 0
29         self.title = None
30         self.refresh = None
31         self.icon = None
32
33     def end_head(self):
34         raise HTMLHeadDone()
35
36     def do_meta(self, attrs):
37         http_equiv = ""
38         content = ""
39
40         for attrname, value in attrs:
41             if value:
42                 value = value.strip()
43                 if attrname == 'http-equiv':
44                     http_equiv = value.lower()
45                 elif attrname == 'content':
46                     content = value
47                 elif (attrname == 'charset') and (not self.charset):
48                     self.charset = value.lower()
49                     self.meta_charset = 1
50
51         if (not self.charset) and (http_equiv == "content-type"):
52             try:
53                 # extract charset from
54                 # "text/html; foo; charset=UTF-8, bar; baz;"
55                 self.charset = content.lower().split('charset=')[1].\
56                     split(';')[0].split(',')[0]
57                 # Remember that the charset was retrieved from
58                 # META tag, not from the Content-Type header
59                 self.meta_charset = 1
60             except IndexError:
61                 pass
62
63         if http_equiv == "refresh":
64             self.refresh = content
65
66     def start_title(self, attrs):
67         self.accumulator = ''
68
69     def end_title(self):
70         if not self.title:  # use only the first title
71             self.title = self.accumulator
72
73     def do_link(self, attrs):
74         has_icon = False
75         href = None
76
77         for attrname, value in attrs:
78             if value:
79                 value = value.strip()
80                 if (attrname == 'rel') and (
81                         value.lower() in ('icon', 'shortcut icon')
82                 ):
83                     has_icon = True
84                 elif attrname == 'href':
85                     href = value
86
87         if has_icon:
88             self.icon = href
89
90
91 def parse_html(html_text, charset=None, log=None):
92     if not html_text:
93         return None
94     parser = HTMLParser(charset)
95
96     try:
97         parser.feed(html_text)
98     except (HTMLParseError, HTMLHeadDone):
99         pass
100
101     try:
102         parser.close()
103     except (HTMLParseError, HTMLHeadDone):
104         pass
105
106     if (parser.title is None) and (parser.refresh is None) \
107             and (parser.icon is None):
108         return None
109     return parser