在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 相关文章推荐
Django1.3添加app提示模块不存在的解决方法
Aug 26 Python
Python实现获取域名所用服务器的真实IP
Oct 25 Python
python开发之thread线程基础实例入门
Nov 11 Python
Python实现字符串格式化的方法小结
Feb 20 Python
Mac中Python 3环境下安装scrapy的方法教程
Oct 26 Python
python enumerate函数的使用方法总结
Nov 15 Python
OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
Jan 05 Python
Python实现DDos攻击实例详解
Feb 02 Python
python的pytest框架之命令行参数详解(下)
Jun 27 Python
分享一个pycharm专业版安装的永久使用方法
Sep 24 Python
在Django中预防CSRF攻击的操作
Mar 13 Python
django 模版关闭转义方式
May 14 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
SONY ICF-SW7600的电路分析
2021/03/02 无线电
PHP 文件编程综合案例-文件上传的实现
2013/07/03 PHP
用PHP实现弹出消息提示框的两种方法
2013/12/17 PHP
教你在header中隐藏php的版本信息
2016/08/10 PHP
手把手编写PHP框架 深入了解MVC运行流程
2016/09/19 PHP
PHP面向对象程序设计子类扩展父类(子类重新载入父类)操作详解
2019/06/14 PHP
PHP架构及原理知识点详解
2019/12/22 PHP
Prototype Template对象 学习
2009/07/19 Javascript
用jquery中插件dialog实现弹框效果实例代码
2013/11/15 Javascript
jQuery实现tag便签去重效果的方法
2015/01/20 Javascript
JS实现自适应高度表单文本框的方法
2015/02/25 Javascript
jQuery实现带延迟效果的滑动菜单代码
2015/09/02 Javascript
jquery跟随屏幕滚动效果的实现代码
2016/04/13 Javascript
jQuery内容折叠效果插件用法实例分析(附demo源码)
2016/04/28 Javascript
限制复选框最多选择项的实现代码
2016/05/30 Javascript
JS判断来路是否是百度等搜索索引进行弹窗或自动跳转的实现代码
2016/10/09 Javascript
jQuery实现花式轮播之圣诞节礼物传送效果
2016/12/25 Javascript
Vue.js实现表格动态增加删除的方法(附源码下载)
2017/01/20 Javascript
jQuery插件FusionCharts绘制2D柱状图和折线图的组合图效果示例【附demo源码】
2017/04/10 jQuery
JQuery事件委托原理与用法实例分析
2019/05/13 jQuery
node省市区三级数据性能测评实例分析
2019/11/06 Javascript
JS实现页面侧边栏效果探究
2021/01/08 Javascript
Python greenlet实现原理和使用示例
2014/09/24 Python
python获取android设备的GPS信息脚本分享
2015/03/06 Python
Python 操作 PostgreSQL 数据库示例【连接、增删改查等】
2020/04/21 Python
python构造IP报文实例
2020/05/05 Python
python 三种方法实现对Excel表格的读写
2020/11/19 Python
python语言time库和datetime库基本使用详解
2020/12/25 Python
幼儿园教师培训制度
2014/01/16 职场文书
环保志愿者活动方案
2014/08/14 职场文书
招标授权委托书样本
2014/09/23 职场文书
公务员政审材料
2014/12/23 职场文书
清洁工个人总结
2015/03/04 职场文书
python学习之panda数据分析核心支持库
2021/05/07 Python
MySQL窗口函数的具体使用
2021/11/17 MySQL
实操Python爬取觅知网素材图片示例
2021/11/27 Python