TypeError: не може використовувати рядовий візерунок на об’єкті, подібному до байтів, в re.findall ()


107

Я намагаюся навчитися автоматично отримувати URL-адреси зі сторінки. У наступному коді я намагаюся отримати назву веб-сторінки:

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)

І я отримую цю несподівану помилку:

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

Що я роблю неправильно?


Відповіді:



28

Проблема полягає в тому, що ваш регулярний вираз є рядком, але htmlє байтами :

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

Оскільки python не знає, як кодуються ці байти, він викидає виняток, коли ви намагаєтесь використовувати для них рядковий шрифт.

Ви можете або decodeбайти в рядок:

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

Або скористайтеся байтовим виразом:

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

У цьому конкретному контексті ви можете отримати кодування з заголовків відповідей:

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

Детальнішу інформацію див. У urlopenдокументації .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.