Как обрабатывать IncompleteRead: в python

Я пытаюсь получить некоторые данные с веб-сайта. Однако он возвращает меня incomplete read. Данные, которые я пытаюсь получить, - это огромный набор вложенных ссылок. Я провел некоторое исследование в Интернете и обнаружил, что это может быть связано с ошибкой сервера достигая ожидаемого размера). Я также нашел обходное решение для выше на этой ссылке

Однако я не уверен, как использовать это для моего дела. Ниже приведен код, над которым я работаю

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

Пожалуйста, помогите мне с этим. Спасибо

Ответ 1

Ссылка которую вы включили в свой вопрос, представляет собой просто оболочку, которая выполняет функцию urllib read(), которая ловит любые незавершенные исключения для чтения для вас, Если вы не хотите внедрять весь этот патч, вы всегда можете просто вставить цикл try/catch, где будете читать ваши ссылки. Например:

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

для python3

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

Ответ 2

Я узнаю в своем случае: отправьте запрос HTTP/1.0, добавив это, устраните проблему.

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

после выполнения запроса:

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

после того, как я вернусь к http 1.1 с (для соединений, поддерживающих 1.1):

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

трюк использует http 1.0 вместо стандартного http/1.1 http 1.1 может обрабатывать куски, но по какой-то причине веб-сервер этого не делает, поэтому мы делаем запрос в http 1.0

Ответ 3

То, что сработало для меня, - это выхватить IncompleteRead как исключение и собрать данные, которые вам удалось прочитать на каждой итерации, поставив их в цикл, как показано ниже: (Примечание. Я использую Python 3.4.1, и библиотека urllib изменилась между 2.7 и 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__())

Ответ 4

Вы можете использовать requests вместо urllib2. requests основан на urllib3, поэтому он редко сталкивается с какой-либо проблемой. Поместите его в цикл, чтобы попробовать его 3 раза, и он будет намного сильнее. Вы можете использовать его следующим образом:

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

Ответ 5

Я обнаружил, что причиной этого является мой детектор вирусов/брандмауэр. "Онлайн-щит" - часть AVG.

Ответ 6

Я пробовал все эти решения, и никто из них не работал у меня. На самом деле, что работала вместо использования urllib, я просто использовал http.client(Python 3)

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

Это работает отлично каждый раз, тогда как с urllib он каждый раз возвращал исключение без пробелов.

Ответ 7

Я просто добавляю больше исключений, чтобы передать эту проблему.
точно так же, как

try:
    r = requests.get(url, timeout=timeout)

except (requests.exceptions.ChunkedEncodingError, requests.ConnectionError) as e:
    logging.error("There is a error: %s" % e)

Ответ 8

В основном это происходит, когда сайт, на котором вы читаете данные, перегружен, чтобы решить эту проблему, и повторите попытку повторно. Это помогло мне.

    try:
        r = requests.get(url, timeout=timeout)

    except (requests.exceptions.ChunkedEncodingError) as e:
        r=request.get(url,timeout=timeout)