在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 相关文章推荐
c++生成dll使用python调用dll的方法
Jan 20 Python
初学Python实用技巧两则
Aug 29 Python
python下载文件时显示下载进度的方法
Apr 02 Python
从Python的源码来解析Python下的freeblock
May 11 Python
python通过Windows下远程控制Linux系统
Jun 20 Python
python实现抖音点赞功能
Apr 07 Python
python中的数据结构比较
May 13 Python
基于python判断目录或者文件代码实例
Nov 29 Python
Python有参函数使用代码实例
Jan 06 Python
Tensorflow不支持AVX2指令集的解决方法
Feb 03 Python
对tensorflow中cifar-10文档的Read操作详解
Feb 10 Python
python中plt.imshow与cv2.imshow显示颜色问题
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
PHP 文件扩展名 获取函数
2009/06/03 PHP
ThinkPHP中处理表单中的注意事项
2014/11/22 PHP
php伪静态验证码不显示的解决方案
2019/09/26 PHP
button没写type=button会导致点击时提交
2014/03/06 Javascript
javascript检测浏览器的缩放状态实现代码
2014/09/28 Javascript
JavaScript中的对象的extensible属性介绍
2014/12/30 Javascript
js实现分享到随页面滚动而滑动效果的方法
2015/04/10 Javascript
javascript实现tab切换特效
2015/11/12 Javascript
jQuery增加与删除table列的方法
2016/03/01 Javascript
基于jQuery实现淡入淡出效果轮播图
2020/07/31 Javascript
Boostrap实现的登录界面实例代码
2016/10/09 Javascript
JavaScript之DOM插入更新删除_动力节点Java学院整理
2017/07/03 Javascript
JavaScript伪数组用法实例分析
2017/12/22 Javascript
swiper动态改变滑动内容的实现方法
2018/01/17 Javascript
微信小程序dom操作的替代思路实例分析
2018/12/06 Javascript
微信小程序实现简单表格
2019/02/14 Javascript
vue全屏事件开发详解
2020/06/17 Javascript
JS+CSS实现炫酷光感效果
2020/09/05 Javascript
Python实现公历(阳历)转农历(阴历)的方法示例
2017/08/22 Python
Python下使用Scrapy爬取网页内容的实例
2018/05/21 Python
Pycharm使用之设置代码字体大小和颜色主题的教程
2019/07/12 Python
Flask框架学习笔记之使用Flask实现表单开发详解
2019/08/12 Python
python科学计算之scipy——optimize用法
2019/11/25 Python
python pygame实现滚动横版射击游戏城市之战
2019/11/25 Python
Python实现实时数据采集新型冠状病毒数据实例
2020/02/04 Python
python爬虫开发之Request模块从安装到详细使用方法与实例全解
2020/03/09 Python
Keras - GPU ID 和显存占用设定步骤
2020/06/22 Python
python中upper是做什么用的
2020/07/20 Python
使用canvas一步步实现图片打码功能的方法
2019/06/17 HTML / CSS
银行类自荐信
2014/02/04 职场文书
广告词串烧
2014/03/19 职场文书
机关干部个人对照检查材料思想汇报
2014/09/28 职场文书
离婚起诉状范本
2015/05/19 职场文书
JavaScript实现班级抽签小程序
2021/05/19 Javascript
opencv深入浅出了解机器学习和深度学习
2022/03/17 Python
进行数据处理的6个 Python 代码块分享
2022/04/06 Python