在scrapy中使用phantomJS实现异步爬取的方法
使用selenium能够非常方便的获取网页的ajax内容,并且能够模拟用户点击和输入文本等诸多操作,这在使用scrapy爬取网页的过程中非常有用。
网上将selenium集成到scrapy的文章很多,但是很少有能够实现异步爬取的,下面这段代码就重写了scrapy的downloader,同时实现了selenium的集成以及异步。
使用时需要PhantomJSDownloadHandler添加到配置文件的DOWNLOADER中。
#encoding:utf-8 from__future__importunicode_literals fromscrapyimportsignals fromscrapy.signalmanagerimportSignalManager fromscrapy.responsetypesimportresponsetypes fromscrapy.xlib.pydispatchimportdispatcher fromseleniumimportwebdriver fromsix.movesimportqueue fromtwisted.internetimportdefer,threads fromtwisted.python.failureimportFailure classPhantomJSDownloadHandler(object): def__init__(self,settings): self.options=settings.get('PHANTOMJS_OPTIONS',{}) max_run=settings.get('PHANTOMJS_MAXRUN',10) self.sem=defer.DeferredSemaphore(max_run) self.queue=queue.LifoQueue(max_run) SignalManager(dispatcher.Any).connect(self._close,signal=signals.spider_closed) defdownload_request(self,request,spider): """usesemaphoretoguardaphantomjspool""" returnself.sem.run(self._wait_request,request,spider) def_wait_request(self,request,spider): try: driver=self.queue.get_nowait() exceptqueue.Empty: driver=webdriver.PhantomJS(**self.options) driver.get(request.url) #ghostdriverwon'tresponsewhenswitchwindowuntilpageisloaded dfd=threads.deferToThread(lambda:driver.switch_to.window(driver.current_window_handle)) dfd.addCallback(self._response,driver,spider) returndfd def_response(self,_,driver,spider): body=driver.execute_script("returndocument.documentElement.innerHTML") ifbody.startswith(""):#cannotaccessresponseheaderinSelenium body=driver.execute_script("returndocument.documentElement.textContent") url=driver.current_url respcls=responsetypes.from_args(url=url,body=body[:100].encode('utf8')) resp=respcls(url=url,body=body,encoding="utf-8") response_failed=getattr(spider,"response_failed",None) ifresponse_failedandcallable(response_failed)andresponse_failed(resp,driver): driver.close() returndefer.fail(Failure()) else: self.queue.put(driver) returndefer.succeed(resp) def_close(self): whilenotself.queue.empty(): driver=self.queue.get_nowait() driver.close()
以上这篇在scrapy中使用phantomJS实现异步爬取的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。