修改2
第二种方法。目前,我放弃了使用多个实例并配置了scrapy设置,不使用并发请求。它虽然缓慢但稳定。 我开了赏金。谁可以帮助同时完成这项工作?如果我将scrapy配置为同时运行,则会出现分段错误。
class WebkitDownloader( object ):
def __init__(self):
os.environ["DISPLAY"] = ":99"
self.proxyAddress = "a:b@" + PROXY_DEFAULT_HOST + ":" + str(PROXY_DEFAULT_PORT)
def process_response(self, request, response, spider):
self.request = request
self.response = response
if 'cached' not in response.flags:
webkitBrowser = webkit.WebkitBrowser(proxy = self.proxyAddress, gui=False, timeout=0.5, delay=0.5, forbidden_extensions=['js','css','swf','pdf','doc','xls','ods','odt'])
#print "added to queue: " + str(self.counter)
webkitBrowser.get(html=response.body, num_retries=0)
html = webkitBrowser.current_html()
respcls = responsetypes.from_args(headers=response.headers, url=response.url)
kwargs = dict(cls=respcls, body=killgremlins(html))
response = response.replace(**kwargs)
webkitBrowser.setPage(None)
del webkitBrowser
return response
修改
我试图在此期间回答我自己的问题并实现了一个队列,但由于某种原因它不会异步运行。基本上当webkitBrowser.get(html=response.body, num_retries=0)
忙时,scrapy会被阻止,直到方法完成。新请求未分配给self.queue
中的剩余空闲实例。
任何人都可以指出我正确的方向来完成这项工作吗?
class WebkitDownloader( object ):
def __init__(self):
proxyAddress = "http://" + PROXY_DEFAULT_HOST + ":" + str(PROXY_DEFAULT_PORT)
self.queue = list()
for i in range(8):
self.queue.append(webkit.WebkitBrowser(proxy = proxyAddress, gui=True, timeout=0.5, delay=5.5, forbidden_extensions=['js','css','swf','pdf','doc','xls','ods','odt']))
def process_response(self, request, response, spider):
i = 0
for webkitBrowser in self.queue:
i += 1
if webkitBrowser.status == "WAITING":
break
webkitBrowser = self.queue[i]
if webkitBrowser.status == "WAITING":
# load webpage
print "added to queue: " + str(i)
webkitBrowser.get(html=response.body, num_retries=0)
webkitBrowser.scrapyResponse = response
while webkitBrowser.status == "PROCESSING":
print "waiting for queue: " + str(i)
if webkitBrowser.status == "DONE":
print "fetched from queue: " + str(i)
#response = webkitBrowser.scrapyResponse
html = webkitBrowser.current_html()
respcls = responsetypes.from_args(headers=response.headers, url=response.url)
kwargs = dict(cls=respcls, body=killgremlins(html))
#response = response.replace(**kwargs)
webkitBrowser.status = "WAITING"
return response
我在scrapy中间件中使用WebKit来呈现JavaScript。目前,scrapy配置为一次处理1个请求(无并发)。
我想使用并发(例如,一次8个请求)但是我需要确保8个WebkitBrowser()
实例根据其各自的处理状态接收请求(尽快提出新请求)当WebkitBrowser.get()
完成并准备好接收下一个请求时)
如何使用Python实现这一目标?这是我目前的中间件:
class WebkitDownloader( object ):
def __init__(self):
proxyAddress = "http://" + PROXY_DEFAULT_HOST + ":" + str(PROXY_DEFAULT_PORT)
self.w = webkit.WebkitBrowser(proxy = proxyAddress, gui=True, timeout=0.5, delay=0.5, forbidden_extensions=['js','css','swf','pdf','doc','xls','ods','odt'])
def process_response(self, request, response, spider):
if not ".pdf" in response.url:
# load webpage
self.w.get(html=response.body, num_retries=0)
html = self.w.current_html()
respcls = responsetypes.from_args(headers=response.headers, url=response.url)
kwargs = dict(cls=respcls, body=killgremlins(html))
response = response.replace(**kwargs)
return response
答案 0 :(得分:2)
我没有关注你问题中的所有内容,因为我不知道scrapy而且我不明白会导致段错误的原因,但我想我可以解决一个问题:为什么当webkitBrowser.get忙时scrapy被阻止?
我的“队列”示例中没有看到任何可以提供并行性的内容。通常,可以使用threading
或multiprocessing
模块,以便多个内容可以“并行”运行。而不是简单地调用webkitBrowser.get
,我怀疑你可能想在一个线程中运行它。检索网页是python线程应该运行得相当好的情况。 Python不能同时执行两个CPU密集型任务(由于GIL),但它可以等待来自Web服务器的并行响应。
Here's a recent SO Q/A with example code that might help.
以下是如何帮助您入门的想法。创建Queue。定义一个将此队列作为参数的函数,获取网页并将响应放入队列中。在主程序中,在生成所有get线程后输入while True:
循环:检查队列并处理下一个条目,或time.sleep(.1)
如果它是空的。
答案 1 :(得分:0)
我知道这是一个老问题,但我有类似的问题,希望我偶然发现的这些信息可以帮助其他人解决这个问题:
如果scrapyjs + splash适合您(鉴于您使用的是webkit浏览器,它们很可能,因为它是基于webkit的),它可能是最简单的解决方案;
如果1不起作用,您可以使用scrapyd或multiprocessing with scrapy同时运行多个蜘蛛;
根据您的浏览器渲染主要是等待(对于要渲染的页面),IO密集型或CPU密集型,您可能希望使用扭曲,多线程或多处理的非阻塞睡眠。对于后者,坚持使用scrapy的价值会减少,你可能想要破解一个简单的刮刀(例如A. Jesse Jiryu Davis和Guido van Rossum撰写的网络爬虫:code和document)或创建你自己的。