wake-up-neo.com

Python TypeError unter Regex

Ich habe also diesen Code:

url = 'http://google.com'
linkregex = re.compile('<a\s*href=[\'|"](.*?)[\'"].*?>')
m = urllib.request.urlopen(url)
msg = m.read()
links = linkregex.findall(msg)

Aber dann gibt Python diesen Fehler zurück:

links = linkregex.findall(msg)
TypeError: can't use a string pattern on a bytes-like object

Was habe ich falsch gemacht?

51
kamikaze_pilot

TypeError: can't use a string patternon a bytes-like object

was habe ich falsch gemacht??

Sie haben ein Zeichenfolgenmuster für ein Byteobjekt verwendet. Verwenden Sie stattdessen ein Byte-Muster:

linkregex = re.compile(b'<a\s*href=[\'|"](.*?)[\'"].*?>')
                       ^
            Add the b there, it makes it into a bytes object

(ps:

 >>> from disclaimer include dont_use_regexp_on_html
 "Use BeautifulSoup or lxml instead."

)

70
Lennart Regebro

Wenn Sie Python 2.6 ausführen, gibt es keine "Anforderung" in "urllib". Die dritte Zeile wird also:

m = urllib.urlopen(url) 

Und in Version 3 sollten Sie Folgendes verwenden:

links = linkregex.findall(str(msg))

Weil 'msg' ein Byteobjekt ist und keine Zeichenfolge, wie findall () erwartet. Oder Sie können mit der richtigen Kodierung dekodieren. Wenn zum Beispiel "latin1" die Kodierung ist, dann gilt Folgendes:

links = linkregex.findall(msg.decode("latin1"))
3

Nun, meine Version von Python hat kein urllib mit einem request-Attribut, aber wenn ich "urllib.urlopen (url)" verwende, bekomme ich keinen String zurück, ich bekomme ein Objekt. Dies ist der Typfehler.

1
Jeremy Whitlock

Das Muster und die Zeichenfolge für reguläre Ausdrücke müssen vom gleichen Typ sein. Wenn Sie einen regulären String abgleichen, benötigen Sie ein String-Muster. Wenn Sie einen Byte-String abgleichen, benötigen Sie ein Byte-Muster.

In diesem Fall gibt m.read () einen Byte-String zurück, sodass Sie ein Byte-Muster benötigen. In Python 3 sind reguläre Zeichenfolgen Unicode-Zeichenfolgen, und Sie müssen mit dem Modifizierer b ein Bytezeichenfolgenliteral angeben:

linkregex = re.compile(b'<a\s*href=[\'|"](.*?)[\'"].*?>')
1
Seppo Enarvi

Die URL, die Sie für Google haben, hat für mich nicht funktioniert, also habe ich http://www.google.com/ig?hl=en für ihn verwendet, was für mich funktioniert.

Versuche dies:

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)

Hoffe das hilft.

1
John

Das hat für mich in Python3 funktioniert. Hoffe das hilft

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

Und auch dies, in dem ich b vor Regex hinzugefügt habe, um es in ein Byte-Array zu konvertieren.

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
0
user3022012