【发布时间】:2011-06-01 02:24:00
【问题描述】:
我的代码使用 Python 的 urllib2 在多个线程中发出许多 HTTP GET 请求,将响应写入文件(每个线程一个)。
在执行期间,看起来许多主机查找失败(导致名称或服务未知错误,请参阅附加的错误日志以获取示例)。
这是由于不稳定的 DNS 服务造成的吗?如果主机名没有改变,依赖 DNS 缓存是不好的做法吗? IE。是否应该将单个查找的结果传递到urlopen?
Exception in thread Thread-16:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/home/da/local/bin/ThreadedDownloader.py", line 61, in run
page = urllib2.urlopen(url) # get the page
File "/usr/lib/python2.6/urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "/usr/lib/python2.6/urllib2.py", line 391, in open
response = self._open(req, data)
File "/usr/lib/python2.6/urllib2.py", line 409, in _open
'_open', req)
File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain
result = func(*args)
File "/usr/lib/python2.6/urllib2.py", line 1170, in http_open
return self.do_open(httplib.HTTPConnection, req)
File "/usr/lib/python2.6/urllib2.py", line 1145, in do_open
raise URLError(err)
URLError: <urlopen error [Errno -2] Name or service not known>
更新 我的(非常简单的)代码
class AsyncGet(threading.Thread):
def __init__(self,outDir,baseUrl,item,method,numPages,numRows,semaphore):
threading.Thread.__init__(self)
self.outDir = outDir
self.baseUrl = baseUrl
self.method = method
self.numPages = numPages
self.numRows = numRows
self.item = item
self.semaphore = semaphore
def run(self):
with self.semaphore: # 'with' is awesome.
with open( os.path.join(self.outDir,self.item+".xml"), 'a' ) as f:
for i in xrange(1,self.numPages+1):
url = self.baseUrl + \
"method=" + self.method + \
"&item=" + self.item + \
"&page=" + str(i) + \
"&rows=" + str(self.numRows) + \
"&prettyXML"
page = urllib2.urlopen(url)
f.write(page.read())
page.close() # Must remember to close!
信号量是一个BoundedSemaphore,用来约束运行线程的总数。
【问题讨论】:
-
在任何人问之前,是的,有些请求确实成功了。程序结构是:每个baseUrl在1个线程中,对于每个文件,打开baseUrl/file,将数据附加到线程的文件中。 “文件”实际上是动态生成的,如果没有这样的文件,它将为空而不是返回 404。
标签: python multithreading http dns urllib2