Подтвердить что ты не робот

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

Что я сделал не так?

4b9b3361

Ответ 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