2011-01-13 3 views
2

Прямо сейчас, это правда. Gzip, изображения, иногда это не работает.Как изменить эту функцию загрузки в Python?

Как изменить эту функцию загрузки, чтобы она могла работать с чем угодно? (Независимо от gzip или любого заголовка?)

Как автоматически «Обнаруживать« если это gzip? Я не хочу всегда передавать True/False, как сейчас.

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

"это ненадежный. Gzip, изображения, иногда это не работает." что это значит? –

ответ

4

Проверьте Content-Encoding заголовок:

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) 

Если вы имеете дело с сервером, который не сообщает Content-Encoding как Gzip, то вы могли бы быть более агрессивным, просто try ИНГ первым:

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

Чтобы определить, какой тип данных, которые вы скачиваете, вы должны заменить h = opener.open(ree).read() для h = opener.open(ree).

Теперь у вас есть объект ответа. Вы можете анализировать заголовки, используя объект h.headers (dict-like). В частности, вас будет интересовать контент-тип заголовков и кодировка содержимого. Вы можете определить отправляемый контент, анализируя его.

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... 
Смежные вопросы