我尝试根据API的某些处理来获取项目列表并检查其状态更改。该列表将手动填充,数量可能有几千个。
我正在尝试编写一个脚本,该脚本可以同时连接到API,以便继续检查状态更改。对于每个项目,一旦状态更改,检查的尝试必须停止。基于阅读Stackoverflow上的其他帖子(具体来说,What is the fastest way to send 100,000 HTTP requests in Python?),我提出了以下代码。但是在处理完列表一次后脚本总是会停止。我做错了什么?
我面临的另一个问题是键盘中断方法永远不会触发(我尝试使用Ctrl + C但它不会杀死脚本。
from urlparse import urlparse
from threading import Thread
import httplib, sys
from Queue import Queue
requestURLBase = "https://example.com/api"
apiKey = "123456"
concurrent = 200
keepTrying = 1
def doWork():
while keepTrying == 1:
url = q.get()
status, body, url = checkStatus(url)
checkResult(status, body, url)
q.task_done()
def checkStatus(ourl):
try:
url = urlparse(ourl)
conn = httplib.HTTPConnection(requestURLBase)
conn.request("GET", url.path)
res = conn.getresponse()
respBody = res.read()
conn.close()
return res.status, respBody, ourl #Status can be 210 for error or 300 for successful API response
except:
print "ErrorBlock"
print res.read()
conn.close()
return "error", "error", ourl
def checkResult(status, body, url):
if "unavailable" not in body:
print status, body, url
keepTrying = 1
else:
keepTrying = 0
q = Queue(concurrent * 2)
for i in range(concurrent):
t = Thread(target=doWork)
t.daemon = True
t.start()
try:
for value in open('valuelist.txt'):
fullUrl = requestURLBase + "?key=" + apiKey + "&value=" + value.strip() + "&years="
print fullUrl
q.put(fullUrl)
q.join()
except KeyboardInterrupt:
sys.exit(1)
我是Python的新手,因此也可能存在语法错误......我绝对不熟悉多线程,所以也许我也做错了其他事情。
答案 0 :(得分:0)
在代码中,列表只读一次。应该像
try:
while True:
for value in open('valuelist.txt'):
fullUrl = requestURLBase + "?key=" + apiKey + "&value=" + value.strip() + "&years="
print fullUrl
q.put(fullUrl)
q.join()
对于中断事项,请删除checkStatus中的裸except
行或将其设为except Exception
。裸露的例外将捕获所有异常,包括SystemExit
这是sys.exit
引发的并阻止python进程终止。
如果我可以一般地发表一些评论。
我建议的是
checkStatus
获取连接对象。通过这种方式,连接可以保持活跃状态,重新使用,并且创建和销毁它们没有任何开销,并且增加了内存使用量。