在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网络编程之TCP通信实例和socketserver框架使用例子
Apr 25 Python
高效使用Python字典的清单
Apr 04 Python
python绘制双Y轴折线图以及单Y轴双变量柱状图的实例
Jul 08 Python
Python大数据之网络爬虫的post请求、get请求区别实例分析
Nov 16 Python
Python实现微信好友的数据分析
Dec 16 Python
python GUI库图形界面开发之PyQt5 MDI(多文档窗口)QMidArea详细使用方法与实例
Mar 05 Python
python 截取XML中bndbox的坐标中的图像,另存为jpg的实例
Mar 10 Python
150行Python代码实现带界面的数独游戏
Apr 04 Python
Python+Selenium随机生成手机验证码并检查页面上是否弹出重复手机号码提示框
Sep 21 Python
pycharm最新激活码有效期至2100年(亲测可用)
Feb 05 Python
pytorch显存一直变大的解决方案
Apr 08 Python
python基础入门之普通操作与函数(三)
Jun 13 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
Dedecms V3.1 生成HTML速度的优化办法
2007/03/18 PHP
浅析php插件 Simple HTML DOM 用DOM方式处理HTML
2013/07/01 PHP
解决Codeigniter不能上传rar和zip压缩包问题
2014/03/07 PHP
ThinkPHP框架任意代码执行漏洞的利用及其修复方法
2014/07/04 PHP
php版本的cron定时任务执行器使用实例
2014/08/19 PHP
PHP进阶学习之Geo的地图定位算法详解
2019/06/19 PHP
jQuery 解析xml文件
2009/08/09 Javascript
IFrame跨域高度自适应实现代码
2012/08/16 Javascript
js+html+css实现鼠标移动div实例
2013/01/30 Javascript
javascript创建数组之联合数组的使用方法示例
2013/12/26 Javascript
JavaScript实现从数组中选出和等于固定值的n个数
2014/09/03 Javascript
Javascript动态创建div的方法
2015/02/09 Javascript
jquery 实现输入邮箱时自动补全下拉提示功能
2015/10/04 Javascript
JS实现新浪微博效果带遮罩层的弹出框代码
2015/10/12 Javascript
利用Vue.js+Node.js+MongoDB实现一个博客系统(附源码)
2017/04/24 Javascript
关于在vue-cli中使用微信自动登录和分享的实例
2017/06/22 Javascript
基于jQuery的表单填充实例
2017/08/22 jQuery
iView框架问题整理小结
2018/10/16 Javascript
vue动态绑定class选中当前列表变色的方法示例
2018/12/19 Javascript
vue项目创建步骤及路由router
2020/01/14 Javascript
python使用三角迭代计算圆周率PI的方法
2015/03/20 Python
JavaScript实现一维数组转化为二维数组
2018/04/17 Python
pycharm+PyQt5+python最新开发环境配置(踩坑)
2019/02/11 Python
Python 类,property属性(简化属性的操作),@property,property()用法示例
2019/10/12 Python
解决pytorch-yolov3 train 报错的问题
2020/02/18 Python
Python2 与Python3的版本区别实例分析
2020/03/30 Python
Python3如何判断三角形的类型
2020/04/12 Python
pycharm配置安装autopep8自动规范代码的实现
2021/03/02 Python
罗技英国官方网站:Logitech UK
2020/11/03 全球购物
C#里面可以避免一个类被其他类继承么?如何?
2013/09/26 面试题
测试工程师程序员求职信范文
2014/02/20 职场文书
团代会宣传工作方案
2014/05/08 职场文书
代领毕业证委托书
2014/08/02 职场文书
合作协议书格式
2014/08/19 职场文书
领导班子作风建设年个人整改措施
2014/09/29 职场文书
JavaScript如何利用Promise控制并发请求个数
2021/05/14 Javascript