我有一个响应各种用户请求的web.py服务器。其中一个请求涉及下载和分析一系列网页。
有没有一种简单的方法在web.py中设置基于异步/回调的url下载机制?资源使用率低是特别重要的,因为每个用户发起的请求都可能导致下载多个页面。
流程看起来像:
用户请求 - > web.py - >并行或异步下载10页 - >分析内容,返回结果
我认识到Twisted是一个很好的方法,但我已经在web.py中了,所以我对web.py中的内容特别感兴趣。
答案 0 :(得分:6)
这是一段有趣的代码。我自己没有使用它,但它看起来不错;)
https://github.com/facebook/tornado/blob/master/tornado/httpclient.py
低级AsyncHTTPClient:
“使用pycurl支持的非阻塞HTTP客户端。示例用法:”
import ioloop
def handle_request(response):
if response.error:
print "Error:", response.error
else:
print response.body
ioloop.IOLoop.instance().stop()
http_client = httpclient.AsyncHTTPClient()
http_client.fetch("http://www.google.com/", handle_request)
ioloop.IOLoop.instance().start()
” fetch()可以使用字符串URL或HTTPRequest实例,它提供了更多选项,例如执行POST / PUT / DELETE请求。
AsyncHTTPClient构造函数的关键字参数max_clients确定可以在每个IOLoop上并行执行的最大并发fetch()操作数。 “
还有新的实施正在进行中: https://github.com/facebook/tornado/blob/master/tornado/simple_httpclient.py “没有外部依赖关系的非阻塞HTTP客户端。...此类仍在开发中,尚未推荐用于生产。”
答案 1 :(得分:4)
一种选择是将作品发布到某种类型的队列中(您可以使用像ActiveMQ那样pyactivemq或STOMP作为连接器的东西,或者您可以使用轻量级的东西比如Kestrel,它是用Scala编写的,与memcache说的是同一个protocl,所以你可以使用python memcache客户端与它交谈。)
设置排队机制后,您可以创建订阅队列的任意数量的工作任务,并根据需要执行实际的下载工作。您甚至可以让它们在其他机器上运行,这样它们就不会干扰为您的网站提供服务的速度。当工作人员完成后,他们会将结果发布回数据库或网络服务器可以接收的其他队列。
如果您不想管理外部工作进程,那么您可以在运行Web服务器的同一个python进程中创建工作线程,但显然它会更有可能影响您的网页服务性能。
答案 2 :(得分:3)
您可以使用urllib
下载文件,使用Queue
模块来管理多个工作线程。 e.g:
import urllib
from threading import Thread
from Queue import Queue
NUM_WORKERS = 20
class Dnld:
def __init__(self):
self.Q = Queue()
for i in xrange(NUM_WORKERS):
t = Thread(target=self.worker)
t.setDaemon(True)
t.start()
def worker(self):
while 1:
url, Q = self.Q.get()
try:
f = urllib.urlopen(url)
Q.put(('ok', url, f.read()))
f.close()
except Exception, e:
Q.put(('error', url, e))
try: f.close() # clean up
except: pass
def download_urls(self, L):
Q = Queue() # Create a second queue so the worker
# threads can send the data back again
for url in L:
# Add the URLs in `L` to be downloaded asynchronously
self.Q.put((url, Q))
rtn = []
for i in xrange(len(L)):
# Get the data as it arrives, raising
# any exceptions if they occur
status, url, data = Q.get()
if status == 'ok':
rtn.append((url, data))
else:
raise data
return rtn
inst = Dnld()
for url, data in inst.download_urls(['http://www.google.com']*2):
print url, data
答案 3 :(得分:2)
我只是在twisted中构建一个服务,进行并发获取和分析,并从web.py访问它作为一个简单的http请求。
答案 4 :(得分:2)
使用使用asynchat和asyncore的async http客户端。 http://sourceforge.net/projects/asynchttp/files/asynchttp-production/asynchttp.py-1.0/asynchttp.py/download
答案 5 :(得分:2)
答案 6 :(得分:0)
我不确定我是否理解你的问题,所以我会先给出多个部分答案。
答案 7 :(得分:0)
我不知道这是否真的有效,但看起来可能如此:EvServer: Python Asynchronous WSGI Server有一个web.py interface,可以将彗星风格推送到浏览器客户端。
如果这不对,也许您可以使用Concurrence HTTP client进行页面的异步下载,并找出如何通过ajax或comet将它们提供给浏览器。
答案 8 :(得分:0)
根据MarkusQ的回答,MochiKit是一个不错的JavaScript库,具有受Twisted启发的强大的异步方法。
答案 9 :(得分:0)
实际上你可以将twisted与web.py集成在一起。我不太确定我是怎么用django做的(用过它来扭曲)。