背景
我正在开发一个产生7个线程的网络爬虫,每个线程都会查询XML文件的唯一网址。当每个查询收到响应时,它会将响应转换为XML树,如下所示:
Database.Insert("Groups", new { GroupName = "testGroup", CreatedOn = DateTime.Now });
当每个线程启动时,会给它一个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()
放入其中,以便tree
是唯一写入文件的线程。从上面继续:
__主__
__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)
时开始接收AttributeError: 'NoneType' object has no attribute 'write'
。将uTree.write()
快速更改为uTree.write()
表示对象有时会保持完整,有时会变为print(type(uTree))
:
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'>
传递到[{1}} [驻留在threading.Thread()
]上,不一致地更改为queue.Queue()
?
我该如何解决这个问题?
完整代码(如果需要):
main.py
__main__
crawl.py
NoneType
答案 0 :(得分:0)
(我发表评论,但似乎没有声誉)
这不是解决你的问题,但可能会给你一些指示。
我知道调试线程问题比较困难但我建议简化你的例子。您正在使用ElementTree和HTTP连接来解析XML - 这两者似乎都与问题无关。
要解决您的问题,您还可以通过记录您放入队列的内容获得深刻见解。
我建议在将复杂对象(例如已解析的树)放入队列时要格外小心。然后,您需要确保对象的类型本身是线程安全的。
如果您不了解它,我建议使用https://scrapy.org/,这样可以更轻松地实现抓取工具。