在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中使用scapy模拟数据包实现arp攻击、dns放大攻击例子
Oct 23 Python
用实例详解Python中的Django框架中prefetch_related()函数对数据库查询的优化
Apr 01 Python
python使用wmi模块获取windows下硬盘信息的方法
May 15 Python
Python中的函数作用域
May 07 Python
对python中执行DOS命令的3种方法总结
May 12 Python
删除python pandas.DataFrame 的多重index实例
Jun 08 Python
Python+Pandas 获取数据库并加入DataFrame的实例
Jul 25 Python
python3 实现对图片进行局部切割的方法
Dec 05 Python
Python装饰器结合递归原理解析
Jul 02 Python
python中not、and和or的优先级与详细用法介绍
Nov 03 Python
Python 找出英文单词列表(list)中最长单词链
Dec 14 Python
浅谈Python中的正则表达式
Jun 28 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中Session的概念
2006/10/09 PHP
PHP中使用数组指针函数操作数组示例
2014/11/19 PHP
PHP中ajax无刷新上传图片与图片下载功能
2017/02/21 PHP
PHP封装的PDO数据库操作类实例
2017/06/21 PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
2018/08/21 PHP
thinkphp 5框架实现登陆,登出及session登陆状态检测功能示例
2019/10/10 PHP
表单提交验证类
2006/07/14 Javascript
优化innerHTML操作(提高代码执行效率)
2011/08/20 Javascript
javascript 快速排序函数代码
2012/05/30 Javascript
jquery ajax跨域解决方法(json方式)
2014/02/04 Javascript
jQuery浏览器CSS3特写兼容实例
2015/01/19 Javascript
jQuery dataTables与jQuery UI 对话框dialog的使用教程
2016/09/02 Javascript
JavaScript实现url参数转成json形式
2016/09/25 Javascript
jQuery实现文件编码成base64并通过AJAX上传的方法
2018/04/12 jQuery
layui扩展上传组件模拟进度条的方法
2019/09/23 Javascript
vue实现修改图片后实时更新
2019/11/14 Javascript
解决Vue-cli无法编译es6的问题
2020/10/30 Javascript
python3下使用cv2.imwrite存储带有中文路径图片的方法
2018/05/10 Python
Vue的el-scrollbar实现自定义滚动
2018/05/29 Python
python+opencv 读取文件夹下的所有图像并批量保存ROI的方法
2019/01/10 Python
Python2.7实现多进程下开发多线程示例
2019/05/31 Python
Python生成指定数量的优惠码实操内容
2019/06/18 Python
python集合是否可变总结
2019/06/20 Python
使用Python的datetime库处理时间(RPA流程)
2019/11/24 Python
Numpy之reshape()使用详解
2019/12/26 Python
Python如何省略括号方法详解
2020/03/21 Python
实例讲解利用HTML5 Canvas API操作图形旋转的方法
2016/03/22 HTML / CSS
佛罗里达州印第安河新鲜水果:Hale Groves
2017/02/20 全球购物
英文版餐饮业求职信
2013/10/18 职场文书
大学生职业生涯设计书
2014/01/02 职场文书
公司培训欢迎词
2014/01/10 职场文书
生日邀请函范文
2014/01/13 职场文书
教师师德演讲稿
2014/05/06 职场文书
党的群众路线教育实践活动心得体会(乡镇)
2014/11/03 职场文书
使用JS前端技术实现静态图片局部流动效果
2022/08/05 Javascript
win10音频服务未响应怎么解决?win10音频服务未响应未修复的解决方法
2022/08/14 数码科技