TypeError: In re.findall () kann kein Zeichenfolgenmuster für ein byteähnliches Objekt verwendet werden.

106

Ich versuche zu lernen, wie man automatisch URLs von einer Seite abruft. Im folgenden Code versuche ich, den Titel der Webseite zu erhalten:

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)

Und ich bekomme diesen unerwarteten Fehler:

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

Was mache ich falsch?

Inspired_Blue
quelle
1
Mögliches Duplikat von Convert Bytes in eine Python-Zeichenfolge
Mücke

Antworten:

28

Das Problem ist , dass Ihre Regex ein String ist, aber htmlist Bytes :

>>> type(html)
<class 'bytes'>

Da Python nicht weiß, wie diese Bytes codiert sind, wird eine Ausnahme ausgelöst, wenn Sie versuchen, eine reguläre Zeichenfolge für sie zu verwenden.

Sie können entweder decodedie Bytes zu einer Zeichenfolge:

html = html.decode('ISO-8859-1')  # encoding may vary!
title = re.findall(pattern, html)  # no more error

Oder verwenden Sie einen regulären Byte-Ausdruck:

regex = rb'<title>(,+?)</title>'
#        ^

In diesem speziellen Kontext können Sie die Codierung aus den Antwortheadern abrufen:

with urllib.request.urlopen(url) as response:
    encoding = response.info().get_param('charset', 'utf8')
    html = response.read().decode(encoding)

Weitere Informationen finden Sie in der urlopenDokumentation .

Aran-Fey
quelle