Python TypeError в регулярном выражении
Итак, у меня есть этот код:
url = 'http://google.com'
linkregex = re.compile('<a\s*href=[\'|"](.*?)[\'"].*?>')
m = urllib.request.urlopen(url)
msg = m.read()
links = linkregex.findall(msg)
Но тогда python возвращает эту ошибку:
links = linkregex.findall(msg)
TypeError: can't use a string pattern on a bytes-like object
Что я сделал не так?
Ответы
Ответ 1
TypeError: can't use a string pattern
on a bytes-like object
что я сделал неправильно?
Вы использовали шаблон строки в объекте bytes. Вместо этого используйте шаблон байта:
linkregex = re.compile(b'<a\s*href=[\'|"](.*?)[\'"].*?>')
^
Add the b there, it makes it into a bytes object
(пс:
>>> from disclaimer include dont_use_regexp_on_html
"Use BeautifulSoup or lxml instead."
)
Ответ 2
Если вы используете Python 2.6, в "urllib" нет никакого "запроса". Итак, третья строка становится:
m = urllib.urlopen(url)
И в версии 3 вы должны использовать это:
links = linkregex.findall(str(msg))
Потому что "msg" - это объект байтов, а не строка, как ожидает findall(). Или вы можете декодировать, используя правильную кодировку. Например, если "latin1" является кодировкой, тогда:
links = linkregex.findall(msg.decode("latin1"))
Ответ 3
Ну, моя версия Python не имеет urllib с атрибутом request, но если я использую "urllib.urlopen(url)", я не возвращаю строку, я получаю объект. Это ошибка типа.
Ответ 4
URL-адрес, который у вас для Google не работал у меня, поэтому я заменил http://www.google.com/ig?hl=en
на него, который работает для меня.
Попробуйте следующее:
import re
import urllib.request
url="http://www.google.com/ig?hl=en"
linkregex = re.compile('<a\s*href=[\'|"](.*?)[\'"].*?>')
m = urllib.request.urlopen(url)
msg = m.read():
links = linkregex.findall(str(msg))
print(links)
Надеюсь, что это поможет.
Ответ 5
Шаблон регулярного выражения и строка должны быть одного типа. Если вы соответствуете обычной строке, вам нужен шаблон строки. Если вы сопоставляете байтовую строку, вам нужен шаблон байтов.
В этом случае m.read() возвращает строку байтов, поэтому вам нужен шаблон байтов. В Python 3 регулярные строки являются строками unicode, и вам нужен модификатор b, чтобы указать строковый литерал строки:
linkregex = re.compile(b'<a\s*href=[\'|"](.*?)[\'"].*?>')
Ответ 6
Это сработало для меня в python3. Надеюсь, что это поможет
import urllib.request
import re
urls = ["https://google.com","https://nytimes.com","http://CNN.com"]
i = 0
regex = '<title>(.+?)</title>'
pattern = re.compile(regex)
while i < len(urls) :
htmlfile = urllib.request.urlopen(urls[i])
htmltext = htmlfile.read()
titles = re.search(pattern, str(htmltext))
print(titles)
i+=1
А также это, в котором я добавил b перед regex, чтобы преобразовать его в массив байтов.
import urllib.request
import re
urls = ["https://google.com","https://nytimes.com","http://CNN.com"]
i = 0
regex = b'<title>(.+?)</title>'
pattern = re.compile(regex)
while i < len(urls) :
htmlfile = urllib.request.urlopen(urls[i])
htmltext = htmlfile.read()
titles = re.search(pattern, htmltext)
print(titles)
i+=1