Здесь отказоустойчивая реализация HTMLParser
.
Вы можете бросить почти все что угодно на get_title()
без поломок, если случится что-то неожиданное
get_title()
вернет None
.
Когда Parser()
загружает страницу, она кодирует ее в ASCII
независимо от кодировки, используемой на странице, игнорируя любые ошибки.
Было бы тривиально изменить to_ascii()
для преобразования данных в UTF-8
или любую другую кодировку. Просто добавьте аргумент кодирования и переименуйте функцию в нечто вроде to_encoding()
.
По умолчанию HTMLParser()
будет ломаться на сломанном HTML, он даже ломается на тривиальных вещах, таких как несоответствующие теги Чтобы предотвратить такое поведение, я заменил метод ошибок HTMLParser()
на функцию, которая будет игнорировать ошибки.
#-*-coding:utf8;-*-
#qpy:3
#qpy:console
'''
Extract the title from a web page using
the standard lib.
'''
from html.parser import HTMLParser
from urllib.request import urlopen
import urllib
def error_callback(*_, **__):
pass
def is_string(data):
return isinstance(data, str)
def is_bytes(data):
return isinstance(data, bytes)
def to_ascii(data):
if is_string(data):
data = data.encode('ascii', errors='ignore')
elif is_bytes(data):
data = data.decode('ascii', errors='ignore')
else:
data = str(data).encode('ascii', errors='ignore')
return data
class Parser(HTMLParser):
def __init__(self, url):
self.title = None
self.rec = False
HTMLParser.__init__(self)
try:
self.feed(to_ascii(urlopen(url).read()))
except urllib.error.HTTPError:
return
except urllib.error.URLError:
return
except ValueError:
return
self.rec = False
self.error = error_callback
def handle_starttag(self, tag, attrs):
if tag == 'title':
self.rec = True
def handle_data(self, data):
if self.rec:
self.title = data
def handle_endtag(self, tag):
if tag == 'title':
self.rec = False
def get_title(url):
return Parser(url).title
print(get_title('http://www.google.com'))