J'essaie d'apprendre comment récupérer automatiquement les URL d'une page. Dans le code suivant, j'essaie d'obtenir le titre de la page Web:
import urllib.request
import re
url = "http://www.google.com"
regex = r'<title>(,+?)</title>'
pattern = re.compile(regex)
with urllib.request.urlopen(url) as response:
html = response.read()
title = re.findall(pattern, html)
print(title)
Et je reçois cette erreur inattendue:
Traceback (most recent call last):
File "path\to\file\Crawler.py", line 11, in <module>
title = re.findall(pattern, html)
File "C:\Python33\lib\re.py", line 201, in findall
return _compile(pattern, flags).findall(string)
TypeError: can't use a string pattern on a bytes-like object
Qu'est-ce que je fais mal?
Vous voulez convertir le code HTML (un objet de type octet) en chaîne à l'aide de .decode
, par exemple. html = response.read().decode('utf-8')
.
Le problème est que votre expression rationnelle est une chaîne, mais html
est octets :
>>> type(html)
<class 'bytes'>
Comme python ne sait pas comment ces octets sont codés, une exception est générée lorsque vous essayez d'utiliser une expression rationnelle sous forme de chaîne.
Vous pouvez soit decode
les octets en chaîne:
html = html.decode('ISO-8859-1') # encoding may vary!
title = re.findall(pattern, html) # no more error
Ou utilisez une expression rationnelle d'octets:
regex = rb'<title>(,+?)</title>'
# ^
Dans ce contexte particulier, vous pouvez obtenir le codage à partir des en-têtes de réponse:
with urllib.request.urlopen(url) as response:
encoding = response.info().get_param('charset', 'utf8')
html = response.read().decode(encoding)
Reportez-vous à la urlopen
documentation pour plus de détails.