TypeError: không thể sử dụng mẫu chuỗi trên đối tượng giống byte trong re.findall ()


106

Tôi đang cố gắng tìm hiểu cách tự động tìm nạp url từ một trang. Trong đoạn mã sau, tôi đang cố gắng lấy tiêu đề của trang 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)

Và tôi gặp lỗi không mong muốn này:

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

Tôi đang làm gì sai?


1
bản sao có thể xảy ra của Chuyển đổi byte thành chuỗi Python
gnat

Câu trả lời:



28

Vấn đề là regex của bạn là một chuỗi, nhưng htmlbyte :

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

Vì python không biết các byte đó được mã hóa như thế nào, nó sẽ ném ra một ngoại lệ khi bạn cố gắng sử dụng chuỗi regex trên chúng.

Bạn có thể chuyển decodecác byte thành một chuỗi:

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

Hoặc sử dụng byte regex:

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

Trong ngữ cảnh cụ thể này, bạn có thể lấy mã hóa từ các tiêu đề phản hồi:

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

Xem urlopentài liệu để biết thêm chi tiết.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.