在scrapy中使用phantomJS实现异步爬取的方法


Posted in Python onDecember 17, 2018

使用selenium能够非常方便的获取网页的ajax内容,并且能够模拟用户点击和输入文本等诸多操作,这在使用scrapy爬取网页的过程中非常有用。

网上将selenium集成到scrapy的文章很多,但是很少有能够实现异步爬取的,下面这段代码就重写了scrapy的downloader,同时实现了selenium的集成以及异步。

使用时需要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实现异步爬取的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中请使用isinstance()判断变量类型
Aug 25 Python
编写Python脚本来获取Google搜索结果的示例
May 04 Python
python变量不能以数字打头详解
Jul 06 Python
Linux下为不同版本python安装第三方库
Aug 31 Python
使用python编写简单的小程序编译成exe跑在win10上
Jan 15 Python
pandas获取groupby分组里最大值所在的行方法
Apr 20 Python
深入分析python数据挖掘 Json结构分析
Apr 21 Python
Python Datetime模块和Calendar模块用法实例分析
Apr 15 Python
python-numpy-指数分布实例详解
Dec 07 Python
selenium+Chrome滑动验证码破解二(某某网站)
Dec 17 Python
Python无头爬虫下载文件的实现
Apr 02 Python
Python是怎样处理json模块的
Jul 16 Python
Python 通过调用接口获取公交信息的实例
Dec 17 #Python
python用插值法绘制平滑曲线
Feb 19 #Python
selenium在执行phantomjs的API并获取执行结果的方法
Dec 17 #Python
Python脚本完成post接口测试的实例
Dec 17 #Python
python:接口间数据传递与调用方法
Dec 17 #Python
python直接获取API传递回来的参数方法
Dec 17 #Python
python获取url的返回信息方法
Dec 17 #Python
You might like
锁定年轻人的双倍活力 星巴克推出星倍醇即饮浓咖啡
2021/03/03 咖啡文化
PHP设计模式(五)适配器模式Adapter实例详解【结构型】
2020/05/02 PHP
实用javaScript技术-屏蔽类
2006/08/15 Javascript
JQUERY获取form表单值的代码
2010/07/17 Javascript
jquery png 透明解决方案(推荐)
2010/08/21 Javascript
jQuery之选项卡的简单实现
2014/02/28 Javascript
javascript中关于&amp;&amp; 和 || 表达式的小技巧分享
2015/04/10 Javascript
AngularJS实现星星等级评分功能
2016/09/24 Javascript
javascript使用递归算法求两个数字组合功能示例
2017/01/03 Javascript
vue组件中点击按钮后修改输入框的状态实例代码
2017/04/14 Javascript
ReactJS实现表单的单选多选和反选的示例
2017/10/13 Javascript
vue中引入第三方字体文件的方法示例
2018/12/17 Javascript
Vue.js实现可排序的表格组件功能示例
2019/02/19 Javascript
vue实现随机验证码功能的实例代码
2019/04/30 Javascript
Vue实现表格批量审核功能实例代码
2019/05/28 Javascript
通过循环优化 JavaScript 程序
2019/06/24 Javascript
layui table 多行删除(id获取)的方法
2019/09/12 Javascript
[01:40]2014DOTA2国际邀请赛 三冰SOLO赛后采访恶搞
2014/07/09 DOTA
一个小示例告诉你Python语言的优雅之处
2014/07/04 Python
Python随机读取文件实现实例
2017/05/25 Python
python程序 线程队列queue使用方法解析
2019/09/23 Python
Python读取表格类型文件代码实例
2020/02/17 Python
浅析python表达式4+0.5值的数据类型
2020/02/26 Python
详解Pycharm出现out of memory的终极解决方法
2020/03/03 Python
浅谈matplotlib.pyplot与axes的关系
2020/03/06 Python
pycharm 配置svn的图文教程(手把手教你)
2021/01/15 Python
pytorch 实现L2和L1正则化regularization的操作
2021/03/03 Python
俄罗斯旅游网站:Tripadvisor俄罗斯
2017/03/21 全球购物
瑞典首都斯德哥尔摩的多元奢侈时尚品牌:Acne Studios
2017/07/09 全球购物
什么是设计模式
2012/06/17 面试题
工商管理专业应届生求职信
2013/11/04 职场文书
小升初自荐信怎么写
2015/03/26 职场文书
离职信范本
2015/06/23 职场文书
2016中学教师读书心得体会
2016/01/13 职场文书
Redis分布式锁的7种实现
2022/04/01 Redis
python神经网络Xception模型
2022/05/06 Python