Cómo manejar IncompleteRead: en python

Estoy tratando de obtener algunos datos de un sitio web. Sin embargo me devuelve la incomplete read . Los datos que estoy tratando de obtener son un gran conjunto de enlaces nesteds. Hice algunas investigaciones en línea y descubrí que esto podría deberse a un error del servidor (una encoding de transferencia fragmentada finaliza antes de alcanzar el tamaño esperado). También encontré una solución para arriba en este enlace

Sin embargo, no estoy seguro de cómo usar esto para mi caso. A continuación se muestra el código en el que estoy trabajando.

 br = mechanize.Browser() br.addheaders = [('User-agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1;Trident/5.0)')] urls = "http://shop.o2.co.uk/mobile_phones/Pay_Monthly/smartphone/all_brands" page = urllib2.urlopen(urls).read() soup = BeautifulSoup(page) links = soup.findAll('img',url=True) for tag in links: name = tag['alt'] tag['url'] = urlparse.urljoin(urls, tag['url']) r = br.open(tag['url']) page_child = br.response().read() soup_child = BeautifulSoup(page_child) contracts = [tag_c['value']for tag_c in soup_child.findAll('input', {"name": "tariff-duration"})] data_usage = [tag_c['value']for tag_c in soup_child.findAll('input', {"name": "allowance"})] print contracts print data_usage 

Por favor ayúdame con esto. Gracias.

El enlace que incluyó en su pregunta es simplemente un contenedor que ejecuta la función read () de urllib, que detecta cualquier excepción de lectura incompleta para usted. Si no desea implementar todo este parche, siempre puede lanzar un ciclo de prueba / captura donde lea sus enlaces. Por ejemplo:

 try: page = urllib2.urlopen(urls).read() except httplib.IncompleteRead, e: page = e.partial 

para python3

 try: page = request.urlopen(urls).read() except (http.client.IncompleteRead) as e: page = e.partial 

Descubrí en mi caso: enviar solicitud HTTP / 1.0, agregar esto, solucionar el problema.

 import httplib httplib.HTTPConnection._http_vsn = 10 httplib.HTTPConnection._http_vsn_str = 'HTTP/1.0' 

después de hacer la solicitud:

 req = urllib2.Request(url, post, headers) filedescriptor = urllib2.urlopen(req) img = filedescriptor.read() 

después de volver a http 1.1 con (para conexiones que admiten 1.1):

 httplib.HTTPConnection._http_vsn = 11 httplib.HTTPConnection._http_vsn_str = 'HTTP/1.1' 

el truco es usar http 1.0 en lugar de que el http / 1.1 http 1.1 predeterminado podría manejar fragmentos, pero por alguna razón el servidor web no lo hace, por lo que hacemos la solicitud en http 1.0

Lo que funcionó para mí es capturar IncompleteRead como una excepción y recostackr los datos que logró leer en cada iteración poniendo esto en un bucle como el siguiente: (Nota, estoy usando Python 3.4.1 y la biblioteca urllib ha cambiado entre 2.7 y 3.4 )

 try: requestObj = urllib.request.urlopen(url, data) responseJSON="" while True: try: responseJSONpart = requestObj.read() except http.client.IncompleteRead as icread: responseJSON = responseJSON + icread.partial.decode('utf-8') continue else: responseJSON = responseJSON + responseJSONpart.decode('utf-8') break return json.loads(responseJSON) except Exception as RESTex: print("Exception occurred making REST call: " + RESTex.__str__()) 

Puedes usar requests lugar de urllib2 . requests se basan en urllib3 por lo que rara vez tiene algún problema. Ponlo en un bucle para probarlo 3 veces, y será mucho más fuerte. Puedes usarlo de esta manera:

 import requests msg = None for i in [1,2,3]: try: r = requests.get(self.crawling, timeout=30) msg = r.text if msg: break except Exception as e: sys.stderr.write('Got error when requesting URL "' + self.crawling + '": ' + str(e) + '\n') if i == 3 : sys.stderr.write('{0.filename}@{0.lineno}: Failed requesting from URL "{1}" ==> {2}\n'. format(inspect.getframeinfo(inspect.currentframe()), self.crawling, e)) raise e time.sleep(10*(i-1)) 

Encontré que mi detector de virus / firewall estaba causando este problema. “Online Shield” parte de AVG.

Probé todas estas soluciones y ninguna de ellas funcionó para mí. En realidad, lo que funcionó es que en lugar de usar urllib, solo usé http.client (Python 3)

 conn = http.client.HTTPConnection('www.google.com') conn.request('GET', '/') r1 = conn.getresponse() page = r1.read().decode('utf-8') 

Esto funciona perfectamente cada vez, mientras que con urllib devolvía una excepción de lectura incompleta cada vez.

Acabo de agregar una excepción más para pasar este problema.
al igual que

 try: r = requests.get(url, timeout=timeout) except (requests.exceptions.ChunkedEncodingError, requests.ConnectionError) as e: logging.error("There is a error: %s" % e)