2011-01-13 1 views
2

En ce moment, c'est louche. Gzip, images, parfois ça ne marche pas. Comment puis-je modifier cette fonction de téléchargement afin qu'elle puisse fonctionner avec n'importe quoi? (Sans tenir compte de gzip ou de tout en-tête?)Comment modifier cette fonction de téléchargement en Python?

Comment puis-je automatiquement "Détecter" si c'est gzip? Je ne veux pas toujours passer Vrai/Faux, comme je le fais maintenant.

def download(source_url, g = False, correct_url = True): 
    try: 
     socket.setdefaulttimeout(10) 
     agents = ['Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)','Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1)','Microsoft Internet Explorer/4.0b1 (Windows 95)','Opera/8.00 (Windows NT 5.1; U; en)'] 
     ree = urllib2.Request(source_url) 
     ree.add_header('User-Agent',random.choice(agents)) 
     ree.add_header('Accept-encoding', 'gzip') 
     opener = urllib2.build_opener() 
     h = opener.open(ree).read() 
     if g: 
      compressedstream = StringIO(h) 
      gzipper = gzip.GzipFile(fileobj=compressedstream) 
      data = gzipper.read() 
      return data 
     else: 
      return h 
    except Exception, e: 
     return "" 
+0

"il est hasardeux. Gzip, images, parfois, il ne fonctionne pas." Qu'est-ce que ça veut dire? –

Répondre

4

Vérifiez la Content-Encoding tête:

import urllib2 
import socket 
import random 
import StringIO 
import gzip 

def download(source_url): 
    try: 
     socket.setdefaulttimeout(10) 
     agents = ['Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)','Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1)','Microsoft Internet Explorer/4.0b1 (Windows 95)','Opera/8.00 (Windows NT 5.1; U; en)'] 
     ree = urllib2.Request(source_url) 
     ree.add_header('User-Agent',random.choice(agents)) 
     ree.add_header('Accept-encoding', 'gzip') 
     opener = urllib2.build_opener() 
     response = opener.open(ree) 
     encoding=response.headers.getheader('Content-Encoding') 
     content = response.read() 
     if encoding and 'gzip' in encoding: 
      compressedstream = StringIO.StringIO(content) 
      gzipper = gzip.GzipFile(fileobj=compressedstream) 
      data = gzipper.read() 
      return data 
     else: 
      return content 
    except urllib2.URLError as e: 
     return "" 

data=download('http://api.stackoverflow.com/1.0/questions/3708418?type=jsontext') 
print(data) 

Si vous avez affaire à un serveur qui ne signale pas le Content-Encoding gzip, alors vous pourriez être plus agressif en tout try ing premier:

def download(source_url): 
    try: 
     socket.setdefaulttimeout(10) 
     agents = ['Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)','Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1)','Microsoft Internet Explorer/4.0b1 (Windows 95)','Opera/8.00 (Windows NT 5.1; U; en)'] 
     ree = urllib2.Request(source_url) 
     ree.add_header('User-Agent',random.choice(agents)) 
     ree.add_header('Accept-encoding', 'gzip') 
     opener = urllib2.build_opener() 
     response = opener.open(ree) 
     content = response.read() 
     compressedstream = StringIO.StringIO(content) 
     gzipper = gzip.GzipFile(fileobj=compressedstream) 
     try: 
      data = gzipper.read() 
     except IOError: 
      data = content 
     return data   
    except urllib2.URLError as e: 
     return "" 
1

Pour détecter quel type de données que vous vous téléchargez devez remplacer le h = opener.open(ree).read() pour h = opener.open(ree).

Maintenant dans h vous avez l'objet de réponse. Vous pouvez analyser les en-têtes en utilisant l'objet h.headers (dict-like). En particulier, vous serez intéressé par les en-têtes 'content-type' et 'content-encoding'. Vous pouvez déterminer le contenu envoyé en l'analysant.

def download(source_url, correct_url = True): 
    try: 
     socket.setdefaulttimeout(10) 
     agents = ['Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)','Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1)','Microsoft Internet Explorer/4.0b1 (Windows 95)','Opera/8.00 (Windows NT 5.1; U; en)'] 
     ree = urllib2.Request(source_url) 
     ree.add_header('User-Agent',random.choice(agents)) 
     ree.add_header('Accept-encoding', 'gzip') 
     opener = urllib2.build_opener() 
     h = opener.open(ree) 
     if 'gzip' in h.headers.get('content-type', '') or 
      'gzip' in h.headers.get('content-encoding', ''): 
      compressedstream = StringIO(h.read()) 
      gzipper = gzip.GzipFile(fileobj=compressedstream) 
      data = gzipper.read() 
      return data 
     else: 
      return h.read() 
    except Exception, e: 
     return "" 
1
import urllib2 
import StringIO 
import gzip 

req = urllib2.Request('http:/foo/') 
h = urllib2.urlopen(req) 
data = resp.read() 
if 'gzip' in resp.headers['Content-Encoding']: 
    compressedstream = StringIO(h) 
    gzipper = gzip.GzipFile(fileobj=compressedstream) 
    data = gzipper.read() 

# etc... 
Questions connexes