2017-10-20 2 views
0

背景:私は7つのスレッドを生成ウェブクローラーに取り組んでいますオブジェクトがNoneTypeに生成

、それぞれがXMLファイルに一意のURLを照会します。各スレッドが開始されると、それはそれにtreeを置くことができるように

conn = http.client.HTTPSConnection(host = uHost, port = uPort) 
conn.request('GET', url = '/some/url/file.xml') 
resp = conn.getresponse() 
tree = xml.etree.ElementTree.parse(resp) 

、それは、引数としてqueue.Queue()を与えている:各クエリが応答を受信するとそのように、それは、XMLツリーにその応答を回しますその__main__はファイルを書き込む唯一のスレッドです。上記に引き続き:

__main__

def receive(q): 
    while True: 
     try: 
      uTree = q.get() 
      uTree.write('/some/path/file.xml') 
     except queue.Empty: 
      pass 

conn = http.client.HTTPSConnection(host = uHost, port = uPort) 
conn.request('GET', url = '/some/url/file.xml') 
resp = conn.getresponse() 
tree = xml.etree.ElementTree.parse(resp) 
q.put_nowait(tree) 

を生み出したことはしかし、私はuTree.write()を呼び出すときAttributeError: 'NoneType' object has no attribute 'write'を受け始めました。 print(type(uTree))からuTree.write()のクイックチェンジは、彼らがNoneTypeなる、オブジェクトは時々そのまま残るであろうと、他の時間を示した:

<class 'xml.etree.ElementTree.ElementTree'> 
<class 'xml.etree.ElementTree.ElementTree'> 
<class 'xml.etree.ElementTree.ElementTree'> 
<class 'xml.etree.ElementTree.ElementTree'> 
<class 'NoneType'> 
<class 'NoneType'> 
<class 'xml.etree.ElementTree.ElementTree'> 
<class 'xml.etree.ElementTree.ElementTree'> 

質問:

はなぜqueue.Queue()threading.Thread()から渡されたオブジェクトは、[__main__に居住しています]がNoneTypeに一貫して変更されていませんか?

どうすれば解決できますか?

完全なコード(必要な場合):

main.py

import queue 
import crawl # custom module 
import threading 

def crawler(query): 
    while True: 
     try: 
      query.connect() 
      break 
     except: 
      pass 

def receive(q): 
    while True: 
     try: 
      uQuery = q.get() 
      uTree = uQuery.tree 
      uTree.write('/some/path/file.xml') 
     except queue.Empty: 
      pass 

urls = ['/url1.xml', '/url2.xml', ...] 

q = queue.Queue() 

queries = [Query(url, q) for url in urls] 
threads = [threading.Thread(target = crawler, args = (query,)) for query in queres] 

for t in threads: 
    t.start() 

receive(q) 

crawl.py

import http.client 
import xml.etree.ElementTree as ET 

class Query: 
    def __init__(self, url, q): 
     self.url = url 
     self.queue = q 
     self.tree = None 

    def connect(): 
     conn = http.Client.HTTPConnect(host = 'something.com', port = '80') 
     conn.request('GET', url = self.url) 
     resp = conn.getresponse() 
     self.tree = ET.parse(resp) 
     self.queue.put_nowait(self) 
     conn.close() 

答えて

0

(私はコメントしないがしたいです評判があるようです)

これはあなたの問題を解決するものではありませんが、いくつかの参考になります。

私はそれがデバッグスレッドの問題がより困難である知っているが、私はあなたの例を簡素化することをお勧め。 ElementTreeとHTTP接続を使用してXMLの解析を行うことが含まれています。どちらも質問には関係していないようです。あなたも、あなたがキューに入れているものをログインからの洞察を得るかもしれないあなたの問題を解決するために

私はキューには、そのような解析された木のような複雑なオブジェクトを、入れたときに余分な注意するアドバイスです。次に、オブジェクトの種類自体がスレッドセーフであることを確認する必要があります。

あなたはそれに気づいていない場合には、私はそんなに簡単にクローラーを実装させることになるhttps://scrapy.org/を使用してお勧めします。

関連する問題