]> git.phdru.name Git - bookmarks_db.git/blobdiff - Robots/parse_html.py
Some sites put TITLE in HTML outside of HEAD.
[bookmarks_db.git] / Robots / parse_html.py
index 8e5ca2b826a1359b37b13af1b336627f3a59609b..9f924c49597a3f4436fd477363ee7cd1fe1b5c32 100755 (executable)
@@ -11,17 +11,16 @@ from m_lib.defenc import default_encoding
 current_charset = default_encoding.replace("windows-", "cp")
 DEFAULT_CHARSET = "cp1251" # Stupid default for Russian Cyrillic
 
-from parse_html_htmlparser import parse_html as _parse_html
+parsers = []
+try:
+   from parse_html_beautifulsoup import parse_html
+except ImportError:
+   pass
+else:
+   parsers.append(parse_html)
 
-
-class HTMLParser(object):
-   def __init__(self, charset=None):
-      _HTMLParser.__init__(self)
-      self.charset = charset
-      self.meta_charset = 0
-      self.title = ''
-      self.refresh = ''
-      self.icon = None
+from parse_html_htmlparser import parse_html
+parsers.append(parse_html)
 
 
 import re
@@ -31,7 +30,10 @@ def recode_entities(title, charset):
    output = []
    for part in entity_re.split(title):
       if entity_re.match(part):
-         part = unichr(int(part[2:-1])).encode(charset, "replace")
+         try:
+            part = unichr(int(part[2:-1])).encode(charset)
+         except UnicodeEncodeError:
+            pass # Leave the entity as is
       output.append(part)
 
    return ''.join(output)
@@ -44,9 +46,14 @@ def parse_html(filename, charset=None, log=None):
       except (ValueError, LookupError):
          charset = None         # ...try charset from HTML
 
-   parser = _parse_html(filename, charset)
-   title = parser.title
+   for p in parsers:
+      parser = p(filename, charset)
+      if parser:
+         break
+      else:
+         if log: log("Parser %s.%s failed, trying next one." % (p.__module__, p.__name__))
 
+   converted_title = title = parser.title
    if not parser.charset:
       try:
          unicode(title, "ascii")
@@ -61,21 +68,37 @@ def parse_html(filename, charset=None, log=None):
          if parser.meta_charset:
             if log: log("   META charset   : %s" % parser.charset)
          else:
-            if log: log("   charset        : %s" % parser.charset)
-         if log: log("   title          : %s" % title)
-         title = unicode(title, parser.charset, "replace").encode(current_charset, "replace")
+            if log: log("   HTTP charset   : %s" % parser.charset)
          if log: log("   current charset: %s" % current_charset)
-         if log: log("   converted title: %s" % title)
+         if log: log("   title          : %s" % title)
+         save_title = title
+         try:
+            converted_title = unicode(title, parser.charset).encode(current_charset)
+         except UnicodeError:
+            if parser.meta_charset and parser.charset.endswith("1252") and \
+                  not DEFAULT_CHARSET.endswith("1252") and (DEFAULT_CHARSET <> current_charset):
+               parser.charset = DEFAULT_CHARSET
+               if log: log("   incorrect conversion from cp1252, converting from %s" % DEFAULT_CHARSET)
+               converted_title = unicode(save_title, DEFAULT_CHARSET, "replace").encode(current_charset, "replace")
+            else:
+               converted_title = unicode(title, parser.charset, "replace").encode(current_charset, "replace")
+         if log and (converted_title <> title): log("   converted title: %s" % converted_title)
       except LookupError:
          if log: log("   unknown charset: `%s' or `%s'" % (parser.charset, current_charset))
-
-   parser.title = recode_entities(title, current_charset)
+   else:
+      if log: log("   title          : %s" % title)
+
+   final_title = recode_entities(converted_title, current_charset)
+   parts = [s.strip() for s in final_title.replace('\r', '').split('\n')]
+   final_title = ' '.join([s for s in parts if s])
+   if log and (final_title <> converted_title): log("   final title    : %s" % final_title)
+   parser.title = final_title
    return parser
 
 
 if __name__ == '__main__':
    import sys
-   parser = parse_html(sys.argv[1])
+   parser = parse_html(sys.argv[1], current_charset)
    print parser.charset
    print parser.title
    print parser.refresh