python python-2.7 web-scraping beautifulsoup mechanize

Cómo manejar IncompleteRead: en python



python-2.7 web-scraping (7)

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)

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 anidados. Hice algunas investigaciones en línea y descubrí que esto podría deberse a un error del servidor (una codificación de transferencia fragmentada finaliza antes de alcanzar el tamaño esperado). También encontré una solución para arriba en este link

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.


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


El link 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


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


Lo que funcionó para mí es capturar IncompleteRead como una excepción y recopilar los datos que logró leer en cada iteración colocando 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__())


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.


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))