web-dev-qa-db-ja.com

IncompleteReadの処理方法:in python

ウェブサイトからデータを取得しようとしています。しかし、それは私を返しますincomplete read。取得しようとしているデータは、ネストされたリンクの膨大なセットです。私はオンラインで調査を行いましたが、これはサーバーエラー(チャンク転送エンコードが予想サイズに達する前に終了する)が原因である可能性があることがわかりました。また、これに関する上記の回避策を見つけました link

しかし、私の場合にこれをどのように使用するかはわかりません。以下は私が取り組んでいるコードです

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

これで私を助けてください。ありがとう

25
user1967046

質問に含めた link は、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
22
Kyle

私の場合、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()

(1.1をサポートする接続用)でhttp 1.1に戻った後:

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

トリックはデフォルトのhttp/1.1 http 1.1がチャンクを処理できる代​​わりにhttp 1.0を使用することですが、何らかの理由でWebサーバーが処理しないため、http 1.0でリクエストを実行します。

8
Sérgio

urllib2の代わりにrequestsを使用できます。 requestsurllib3に基づいているため、ほとんど問題はありません。ループに入れて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))
1
Aminah Nuraini

私のために働いたのは、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__())
1
gDexter42

ウイルス検出器/ファイアウォールがこの問題を引き起こしていることがわかりました。 AVGの「オンラインシールド」部分。

0
nigel76