在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 实现一个颜色色值转换的小工具
Dec 06 Python
Python3实现发送QQ邮件功能(html)
Dec 15 Python
Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容
Feb 23 Python
Python Flask框架模板操作实例分析
May 03 Python
PyQt4编程之让状态栏显示信息的方法
Jun 18 Python
Django将默认的SQLite更换为MySQL的实现
Nov 18 Python
keras实现基于孪生网络的图片相似度计算方式
Jun 11 Python
Python计算矩阵的和积的实例详解
Sep 10 Python
python3中calendar返回某一时间点实例讲解
Nov 18 Python
Pyside2中嵌入Matplotlib的绘图的实现
Feb 22 Python
Python plt 利用subplot 实现在一张画布同时画多张图
Feb 26 Python
Python进程池与进程锁之语法学习
Apr 11 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调用方法mssql_fetch_row、mssql_fetch_array、mssql_fetch_assoc和mssql_fetch_objcect读取数据的区别
2012/08/08 PHP
php短址转换实现方法
2015/02/25 PHP
highchart数据源纵轴json内的值必须是int(详解)
2017/02/20 PHP
PHP __call()方法实现委托示例
2019/05/20 PHP
Extjs学习笔记之七 布局
2010/01/08 Javascript
用jquery修复在iframe下的页面锚点失效问题
2014/08/22 Javascript
通过JS判断联网类型和连接状态的实现代码
2015/04/01 Javascript
javascript中callee与caller的区别分析
2015/04/20 Javascript
js实现随屏幕滚动的带缓冲效果的右下角广告代码
2015/09/04 Javascript
JQuery日历插件My97DatePicker日期范围限制
2016/01/20 Javascript
基于javascript实现样式清新图片轮播特效
2016/03/30 Javascript
JavaScript实现水平进度条拖拽效果
2017/01/18 Javascript
Node.js Express 框架 POST方法详解
2017/01/23 Javascript
如何使用Bootstrap 按钮实例详解
2017/03/29 Javascript
Bootstrap fileinput文件上传组件使用详解
2017/06/06 Javascript
layui树形菜单动态遍历的例子
2019/09/23 Javascript
Vue页面切换和a链接的本质区别详解
2019/11/12 Javascript
Node.js中的异步生成器与异步迭代详解
2021/01/31 Javascript
[49:20]2014 DOTA2国际邀请赛中国区预选赛5.21 CIS VS TongFu
2014/05/22 DOTA
[02:27]2018DOTA2亚洲邀请赛趣味视频之钓鱼大赛 谁是垂钓冠军?
2018/04/05 DOTA
Tensorflow的可视化工具Tensorboard的初步使用详解
2018/02/11 Python
Selenium获取登录Cookies并添加Cookies自动登录的方法
2020/12/04 Python
CSS3 box-sizing属性详解
2016/11/15 HTML / CSS
html5如何及时更新缓存文件(js、css或图片)
2013/06/24 HTML / CSS
瑞典领先的汽车零部件网上零售商:bildelaronline24.se
2017/01/12 全球购物
施华洛世奇意大利官网:SWAROVSKI意大利
2018/07/23 全球购物
提高EJB性能都有哪些技巧
2012/03/25 面试题
毕业生求职简历的自我评价
2013/10/07 职场文书
大学社团活动策划书
2014/01/26 职场文书
分公司任命书
2014/06/06 职场文书
推广普通话共筑中国梦演讲稿
2014/09/21 职场文书
民主生活会对照检查材料
2014/09/22 职场文书
暑期实践个人总结
2015/03/06 职场文书
面试复试通知单
2015/04/24 职场文书
2015年学校团委工作总结
2015/05/26 职场文书
《学会看病》教学反思
2016/02/17 职场文书