2010-10-16 13 views
63

J'utiliseEst-ce que python urllib2 décompresse automatiquement les données gzip récupérées à partir de la page Web?

data=urllib2.urlopen(url).read() 

Je veux savoir:

  1. Comment puis-je savoir si les données à une URL est gzippés?

  2. Est-ce que urllib2 décompresse automatiquement les données si elles sont gzippées? Est-ce que les données seront toujours une chaîne?

+3

Notez peut-être que la bibliothèque ['requests'] (http://www.python-requests.org/) gère automatiquement la compression gzip (voir [la FAQ] (http://www.python-requests.org/en/last/community/faq/# encoded-data)) – dbr

Répondre

137
  1. Comment puis-je savoir si les données à une URL est gzippés?

Ce vérifie si le contenu est au format gzip et décompresse:

from StringIO import StringIO 
import gzip 

request = urllib2.Request('http://example.com/') 
request.add_header('Accept-encoding', 'gzip') 
response = urllib2.urlopen(request) 
if response.info().get('Content-Encoding') == 'gzip': 
    buf = StringIO(response.read()) 
    f = gzip.GzipFile(fileobj=buf) 
    data = f.read() 
  1. Est-ce que urllib2 décompressez automatiquement les données si elle est gzippés? Est-ce que les données seront toujours une chaîne?

Non, le urllib2 ne décompresse automatiquement les données parce que le « Accept-Encoding » en-tête est pas définie par la urllib2 mais vous en utilisant: request.add_header('Accept-Encoding','gzip, deflate')

+2

bobince a un point, urllib2 n'envoie pas les en-têtes appropriés, donc la réponse ne sera pas gzippée. – daniyalzade

+0

@daysleeper: bon point en effet, j'avais oublié d'inclure l'entête d'acceptation. J'ai modifié le code maintenant. Merci. – ars

+7

Dans Py3k, utilisez io.BytesIO au lieu de StrinIO.StringIO! – phobie

7

Si vous parlez d'une simple .gz fichier, non, urllib2 ne sera pas le décoder, vous obtiendrez le fichier inchangé .gz en sortie. Si vous parlez de la compression automatique au niveau HTTP en utilisant Content-Encoding: gzip ou deflate, cela doit être délibérément demandé par le client en utilisant un en-tête Accept-Encoding.

urllib2 ne définit pas cet en-tête, donc la réponse qu'il récupère ne sera pas compressée. Vous pouvez récupérer la ressource en toute sécurité sans avoir à vous soucier de la compression (bien que la compression ne soit pas prise en charge, la demande peut prendre plus de temps).

+4

Cela ne semble pas être vrai pour tous les serveurs populaires. Essayez 'curl -vI http://en.wikipedia.org/wiki/Spanish_language | & grep '^ [<>]'' –

5

Votre question a été répondue, mais pour une implémentation plus complète, jetez un oeil à Mark Pilgrim's implementation of this, il couvre gzip, deflate, analyse d'URL sûre et beaucoup, beaucoup plus, pour un analyseur RSS largement utilisé, mais néanmoins utile référence.

+0

FYI, lien maintenant mort. – Nick

+0

J'ai mis à jour le lien. – RuiDC