web-dev-qa-db-fra.com

Python TypeError sur regex

Donc, j'ai ce code:

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

Mais alors python renvoie cette erreur:

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

Qu'ai-je fait de mal?

51
kamikaze_pilot

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

qu'ai-je fait de mal??

Vous avez utilisé un modèle de chaîne sur un objet octet. Utilisez plutôt un modèle d'octets:

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

Si vous utilisez Python 2.6, il n'y a pas de "requête" dans "urllib". Donc, la troisième ligne devient:

m = urllib.urlopen(url) 

Et dans la version 3, vous devriez utiliser ceci:

links = linkregex.findall(str(msg))

Parce que 'msg' est un objet bytes et non une chaîne comme le prévoit findall (). Ou vous pouvez décoder en utilisant le codage correct. Par exemple, si "latin1" est l'encodage, alors:

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

Eh bien, ma version de Python ne dispose pas d’urllib avec un attribut request mais si j’utilise "urllib.urlopen (url)", je ne récupère pas de chaîne, j’obtiens un objet. C'est l'erreur de type.

1
Jeremy Whitlock

Le modèle d'expression régulière et la chaîne doivent être du même type. Si vous faites correspondre une chaîne normale, vous avez besoin d'un modèle de chaîne. Si vous faites correspondre une chaîne d'octets, vous avez besoin d'un modèle d'octets.

Dans ce cas, m.read () renvoie une chaîne d'octets, vous avez donc besoin d'un modèle d'octets. En Python 3, les chaînes normales sont des chaînes unicode et vous devez utiliser le modificateur b pour spécifier un littéral de chaîne d'octet:

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

L'URL que vous avez pour Google n'a pas fonctionné pour moi, alors j'ai substitué http://www.google.com/ig?hl=en à celle qui fonctionne pour moi.

Essaye ça:

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)

J'espère que cela t'aides.

1
John

Cela a fonctionné pour moi en python3. J'espère que cela t'aides

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

Et aussi cela dans lequel j'ai ajouté b before regex pour le convertir en tableau d'octets.

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