在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 相关文章推荐
Python2中的raw_input() 与 input()
Jun 12 Python
学习python类方法与对象方法
Mar 15 Python
python爬取51job中hr的邮箱
May 14 Python
详解Python 实现元胞自动机中的生命游戏(Game of life)
Jan 27 Python
Numpy中转置transpose、T和swapaxes的实例讲解
Apr 17 Python
利用Python在一个文件的头部插入数据的实例
May 02 Python
python 定义n个变量方法 (变量声明自动化)
Nov 10 Python
Python简单处理坐标排序问题示例
Jul 11 Python
django多对多表的创建,级联删除及手动创建第三张表
Jul 25 Python
Pytorch GPU显存充足却显示out of memory的解决方式
Jan 13 Python
python使用布隆过滤器的实现示例
Aug 20 Python
Python中正则表达式对单个字符,多个字符和匹配边界等使用
Jan 27 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项目开发中最常用的自定义函数整理
2010/12/02 PHP
理解php Hash函数,增强密码安全
2011/02/25 PHP
PHP仿博客园 个人博客(2) 数据库增添改删
2013/07/05 PHP
Win下如何安装PHP的APC拓展
2013/08/07 PHP
php递归json类实例
2014/12/02 PHP
PHP程序中使用adodb连接不同数据库的代码实例
2015/12/19 PHP
Yii使用技巧大汇总
2015/12/29 PHP
Yii视图CGridView实现操作按钮定义地址示例
2016/07/14 PHP
PHP常用函数之根据生日计算年龄功能示例
2019/10/21 PHP
去除链接虚线全面分析总结
2006/08/15 Javascript
js阻止事件追加的具体实现
2014/10/15 Javascript
JavaScript中window.showModalDialog()用法详解
2014/12/18 Javascript
JS实现选中当前菜单后高亮显示的导航条效果
2015/10/15 Javascript
Angular 根据 service 的状态更新 directive
2016/04/03 Javascript
vue.js绑定class和style样式(6)
2016/12/09 Javascript
jQuery事件与动画基础详解
2017/02/23 Javascript
原生JS实现图片网格式渐显、渐隐效果
2017/06/05 Javascript
浅谈vue-cli 3.0.x 初体验
2018/04/11 Javascript
基于javascript实现碰撞检测
2020/03/12 Javascript
对pandas replace函数的使用方法小结
2018/05/18 Python
Python一键查找iOS项目中未使用的图片、音频、视频资源
2019/08/12 Python
Python爬虫入门有哪些基础知识点
2020/06/02 Python
keras输出预测值和真实值方式
2020/06/27 Python
CSS3绘制有活力的链接下划线
2016/07/14 HTML / CSS
英国男士时尚网站:Dandy Fellow
2018/02/09 全球购物
英国最大最好的无人机商店:Drones Direct
2019/07/12 全球购物
儿子婚宴答谢词
2014/01/09 职场文书
小学英语教学反思
2014/01/30 职场文书
大学校务公开实施方案
2014/03/31 职场文书
婚前协议书
2014/04/15 职场文书
五一口号
2014/06/19 职场文书
奥巴马当选演讲稿
2014/09/10 职场文书
大学生就业协议书范本(适用于公司企业)
2014/10/07 职场文书
中班下学期幼儿评语
2014/12/30 职场文书
预备党员介绍人意见
2015/06/01 职场文书
入党积极分子党小组意见
2015/06/02 职场文书