2011-02-13 12 views
28

Estoy tratando de buscar una página web usando expresiones regulares, pero estoy consiguiendo el error siguiente:Cómo manejar la codificación respuesta de urllib.request.urlopen()

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

entiendo por qué, urllib. request.urlopen() devuelve un bytestream y por lo tanto, al menos estoy adivinando, re no sabe qué codificación usar. ¿Qué se supone que debo hacer en esta situación? ¿Hay alguna forma de especificar el método de codificación en una solicitud en línea? ¿Necesitaré volver a codificar la cadena? Si es así, ¿qué estoy buscando hacer, supongo que debería leer la codificación de la información del encabezado o el tipo de codificación si se especifica en el html y luego volver a codificarlo a eso?

Respuesta

35

Solo tiene que decodificar la respuesta, utilizando el encabezado Content-Type, generalmente el último valor. También hay un ejemplo dado en the tutorial.

output = response.decode('utf-8') 
+0

Gracias, eso es lo que necesitaba. – kryptobs2000

+9

¿Qué sucede si el juego de caracteres no es utf-8? ¿Sería una mejor idea determinarlo de alguna manera a partir de la respuesta en lugar de codificar esta suposición? –

0

después de hacer una solicitud req = urllib.request.urlopen(...) tiene que leer la solicitud llamando al html_string = req.read() que le dará la respuesta de cadena que luego puede analizar de la manera que desee.

+1

Sí, así es como lo obtengo, pero devuelve un equipo de bytes, b ' ...'. – kryptobs2000

+0

veo, luego puede usar '.decode()' como @Senthil señaló o puede usar urllib2 que debería manejar esto de manera transparente para usted. –

0
urllib.urlopen(url).headers.getheader('Content-Type') 

seria algo como esto:

text/html; charset=utf-8

57

En cuanto a mí, la solución es la siguiente (python3):

resource = urllib.request.urlopen(an_url) 
content = resource.read().decode(resource.headers.get_content_charset()) 
+4

Parece la mejor respuesta, pero ¿qué sucede si el servidor no envía la información del juego de caracteres? – rvighne

+0

Si el servidor no envía información de charset, su mejor apuesta en ese momento es adivinar. – Iguananaut

+8

@rvighne: si el servidor no pasa 'charset' en el encabezado' Content-Type', entonces [hay reglas complejas para descubrir la codificación de caracteres] (https://blog.whatwg.org/the-road-to -html-5-character-encoding) por ejemplo, se puede especificar dentro del documento html: ''. – jfs

5

que tenía los mismos problemas durante los últimos dos días. Finalmente tengo una solución. estoy usando el método del objeto devuelto por urlopen()info():

req=urllib.request.urlopen(URL) 
charset=req.info().get_content_charset() 
content=req.read().decode(charset) 
6

Con requests:

import requests 

response = requests.get(URL).text 
2

ninguna de estas respuestas me funciona en Python 3.5x utilizando urllib.request porque urllib .request.urlopen (url) literalmente devuelve SOLAMENTE una secuencia de bytes - NO tiene funciones miembro para analizar ningún tipo de encabezado en el html. Entonces no hay información(), no hay encabezados, etc. Tendría que analizarlo yo mismo para encontrar la codificación, pero sin la codificación no puedo convertirla en texto para analizarla. Es una captura 22.

Cuestiones relacionadas