2012-01-26 9 views
0

マルチスレッドの例は、 Python urllib2.urlopen() is slow, need a better way to read several urlsにありますが、「スレッドエラー」が発生するようですが、これが実際に何を意味するのかわかりません。私は時々、データをフェッチするように見えるんことがわかり、一方urllib2とスレッディング

Exception in thread Thread-1: 
Traceback (most recent call last): 
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner 
self.run() 
File "/usr/lib/python2.7/threading.py", line 505, in run 
self.__target(*self.__args, **self.__kwargs) 
File "demo.py", line 76, in read_url 
print('Fetched %s from %s' % (len(data), url)) 
TypeError: object of type 'instancemethod' has no len() 

、その後私は、次の2番目のエラーを取得:

urlList=[list of urls to be fetched]*100 
def read_url(url, queue): 
my_data=[] 
try: 
    data = urllib2.urlopen(url,None,15).read() 
    print('Fetched %s from %s' % (len(data), url)) 
    my_data.append(data) 
    queue.put(data) 
except HTTPError, e: 
    data = urllib2.urlopen(url).read() 
    print('Fetched %s from %s' % (len(data), url)) 
    my_data.append(data) 
    queue.put(data) 

def fetch_parallel(): 
    result = Queue.Queue() 
    threads = [threading.Thread(target=read_url, args = (url,result)) for url in urlList] 
    for t in threads: 
     t.start() 
    for t in threads: 
     t.join() 
    return result 

res=[] 
res=fetch_parallel() 
reslist = [] 
while not res.empty: reslist.append(res.get()) 
print (reslist) 

私は、次の最初のエラーを取得

Traceback (most recent call last): 
File "demo.py", line 89, in <module> 
print str(res[0]) 
AttributeError: Queue instance has no attribute '__getitem__' 

データをフェッチすると、結果がres []に表示されないのはなぜですか?御時間ありがとうございます。

更新状況は改善しているものの、read_url()関数の中で()読み読み取り変更した後(私は今、多くのページがフェッチ得る)が、それでもエラーました:

Exception in thread Thread-86: 
Traceback (most recent call last): 
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner 
self.run() 
File "/usr/lib/python2.7/threading.py", line 505, in run 
self.__target(*self.__args, **self.__kwargs) 
File "demo.py", line 75, in read_url 
data = urllib2.urlopen(url).read() 
File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen 
return _opener.open(url, data, timeout) 
File "/usr/lib/python2.7/urllib2.py", line 397, in open 
response = meth(req, response) 
File "/usr/lib/python2.7/urllib2.py", line 510, in http_response 
'http', request, response, code, msg, hdrs) 
File "/usr/lib/python2.7/urllib2.py", line 429, in error 
result = self._call_chain(*args) 
File "/usr/lib/python2.7/urllib2.py", line 369, in _call_chain 
result = func(*args) 
File "/usr/lib/python2.7/urllib2.py", line 605, in http_error_302 
return self.parent.open(new, timeout=req.timeout) 
File "/usr/lib/python2.7/urllib2.py", line 397, in open 
response = meth(req, response) 
File "/usr/lib/python2.7/urllib2.py", line 510, in http_response 
'http', request, response, code, msg, hdrs) 
File "/usr/lib/python2.7/urllib2.py", line 435, in error 
return self._call_chain(*args) 
File "/usr/lib/python2.7/urllib2.py", line 369, in _call_chain 
result = func(*args) 
File "/usr/lib/python2.7/urllib2.py", line 518, in http_error_default 
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) 
HTTPError: HTTP Error 502: Bad Gateway 
+1

あなたのゲートウェイをチェックしましたか? – Arafangion

+0

@Arafangion:私は502エラーで何ができるか分からなかった。私はそれを投稿した理由は、マルチスレッドで何かをしなければならないかどうか分からなかったからです。 – JohnJ

答えて

4

注意していますurllib2 is not thread-safe。したがって、実際にurllib3を使用する必要があります。

問題のいくつかはスレッド化とはまったく関係ありません。スレッドはエラー報告をより複雑にするだけです。代わりに

data = urllib2.urlopen(url).read 

のあなたは(ほとんどの場合、あなたは/が使用できません再起動しているために接続しているWebサービスの内部サーバー)

data = urllib2.urlopen(url).read() 
#        ^^ 

502 Bad gatewayエラーは、サーバーの設定ミスを示して欲しいです。あなたができることは何もありません.URLはすぐに到達できません。これらのエラーを処理するには、診断メッセージを出力するか、または適切な待機時間の後に取得するURLをスケジュールするか、失敗したデータセットを省略して、try..exceptを使用します。キューから値を取得するには、次の操作を行うことができます

res = fetch_parallel() 
reslist = [] 
while not res.empty(): 
    reslist.append(res.get_nowait()) # or get, doesn't matter here 
print (reslist) 

URLが実際に到達できない場合には、実際のエラーハンドリング回避する方法もありません。単に再要求するだけの場合もありますが、現時点ではリモートホストが真に到達不能であるというケースを処理できなければなりません。どのように行うかは、アプリケーションのロジックに依存します。

+1

それに感謝します。状況は改善しましたが、まだスレッドエラーが発生します。私はそれに応じて投稿を更新しました。 – JohnJ

+1

502エラーに関する情報で解答を更新しました。より多くの(関連のない)エラーが発生した場合は、新しい質問を開く必要があります。これにより、この質問は他の人のために参考になり、同様の問題を抱えて解答が単純化されます。 – phihag

+0

try:exceptステートメントはどこに行きますか? (申し訳ありませんが、私はスレッドに新しいです)また、どのように文字列としてページを見ることができますか? 「res [0]を印刷するだけで十分ではありませんか?私が "resを印刷"すると、 ""というメッセージが表示されます。 res [0]のようなもの?あなたの提案と回避策をお寄せいただきありがとうございます。 – JohnJ