在scrapy中使用phantomJS實(shí)現(xiàn)異步爬取的方法
使用selenium能夠非常方便的獲取網(wǎng)頁(yè)的ajax內(nèi)容,并且能夠模擬用戶(hù)點(diǎn)擊和輸入文本等諸多操作,這在使用scrapy爬取網(wǎng)頁(yè)的過(guò)程中非常有用。
網(wǎng)上將selenium集成到scrapy的文章很多,但是很少有能夠?qū)崿F(xiàn)異步爬取的,下面這段代碼就重寫(xiě)了scrapy的downloader,同時(shí)實(shí)現(xiàn)了selenium的集成以及異步。
使用時(shí)需要PhantomJSDownloadHandler添加到配置文件的DOWNLOADER中。
# encoding: utf-8
from __future__ import unicode_literals
from scrapy import signals
from scrapy.signalmanager import SignalManager
from scrapy.responsetypes import responsetypes
from scrapy.xlib.pydispatch import dispatcher
from selenium import webdriver
from six.moves import queue
from twisted.internet import defer, threads
from twisted.python.failure import Failure
class PhantomJSDownloadHandler(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)
def download_request(self, request, spider):
"""use semaphore to guard a phantomjs pool"""
return self.sem.run(self._wait_request, request, spider)
def _wait_request(self, request, spider):
try:
driver = self.queue.get_nowait()
except queue.Empty:
driver = webdriver.PhantomJS(**self.options)
driver.get(request.url)
# ghostdriver won't response when switch window until page is loaded
dfd = threads.deferToThread(lambda: driver.switch_to.window(driver.current_window_handle))
dfd.addCallback(self._response, driver, spider)
return dfd
def _response(self, _, driver, spider):
body = driver.execute_script("return document.documentElement.innerHTML")
if body.startswith("<head></head>"): # cannot access response header in Selenium
body = driver.execute_script("return document.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)
if response_failed and callable(response_failed) and response_failed(resp, driver):
driver.close()
return defer.fail(Failure())
else:
self.queue.put(driver)
return defer.succeed(resp)
def _close(self):
while not self.queue.empty():
driver = self.queue.get_nowait()
driver.close()
以上這篇在scrapy中使用phantomJS實(shí)現(xiàn)異步爬取的方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 使用selenium和pyquery爬取京東商品列表過(guò)程解析
- python selenium爬取斗魚(yú)所有直播房間信息過(guò)程詳解
- 詳解python selenium 爬取網(wǎng)易云音樂(lè)歌單名
- Python使用Selenium爬取淘寶異步加載的數(shù)據(jù)方法
- Python使用Selenium+BeautifulSoup爬取淘寶搜索頁(yè)
- python爬蟲(chóng)系列Selenium定向爬取虎撲籃球圖片詳解
- python Selenium爬取內(nèi)容并存儲(chǔ)至MySQL數(shù)據(jù)庫(kù)的實(shí)現(xiàn)代碼
- selenium+PhantomJS爬取豆瓣讀書(shū)
相關(guān)文章
使用Python將Exception異常錯(cuò)誤堆棧信息寫(xiě)入日志文件
這篇文章主要介紹了使用Python將Exception異常錯(cuò)誤堆棧信息寫(xiě)入日志文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
python scipy.spatial.distance 距離計(jì)算函數(shù) ?
本文主要介紹了python scipy.spatial.distance 距離計(jì)算函數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
pandas使用get_dummies進(jìn)行one-hot編碼的方法
今天小編就為大家分享一篇pandas使用get_dummies進(jìn)行one-hot編碼的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
python密碼錯(cuò)誤三次鎖定(實(shí)例講解)
下面小編就為大家分享一篇python密碼錯(cuò)誤三次鎖定的實(shí)例講解。具有很好的參考價(jià)值。希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
pyqt5實(shí)現(xiàn)按鈕添加背景圖片以及背景圖片的切換方法
今天小編就為大家分享一篇pyqt5實(shí)現(xiàn)按鈕添加背景圖片以及背景圖片的切換方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06

