在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实现bucket排序算法实例分析
May 04 Python
HTML中使用python屏蔽一些基本功能的方法
Jul 07 Python
python实现xlsx文件分析详解
Jan 02 Python
Python如何爬取实时变化的WebSocket数据的方法
Mar 09 Python
Python面向对象思想与应用入门教程【类与对象】
Apr 12 Python
python实现将文件夹内的每张图片批量分割成多张
Jul 22 Python
Python图像处理之图片文字识别功能(OCR)
Jul 30 Python
Python从入门到精通之环境搭建教程图解
Sep 26 Python
python 利用jinja2模板生成html代码实例
Oct 10 Python
python Django框架实现web端分页呈现数据
Oct 31 Python
Python networkx包的实现
Feb 14 Python
浅谈keras中的目标函数和优化函数MSE用法
Jun 10 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
用户的详细注册和判断
2006/10/09 PHP
PHP HTML代码串截取代码
2008/12/29 PHP
PHP中文分词 自动获取关键词介绍
2012/11/13 PHP
PHP pear安装配置教程
2016/05/14 PHP
thinkPHP实现签到功能的方法
2017/03/15 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
2017/08/30 PHP
php扩展开发入门demo示例
2019/09/23 PHP
php设计模式之原型模式分析【星际争霸游戏案例】
2020/03/23 PHP
jQuery ui插件的使用方法代码实例
2013/05/08 Javascript
jQuery子属性过滤选择器用法分析
2015/02/10 Javascript
JS组件中bootstrap multiselect两大组件较量
2016/01/26 Javascript
D3.js实现雷达图的方法详解
2016/09/22 Javascript
微信小程序 获取设备信息 API实例详解
2016/10/02 Javascript
完美解决UI-Grid表格元素中多个空格显示为一个空格的问题
2017/04/25 Javascript
jquery实现图片轮播器
2017/05/23 jQuery
nodeJS实现路由功能实例代码
2017/06/08 NodeJs
详解ES6之用let声明变量以及let loop机制
2017/07/15 Javascript
客户端(vue框架)与服务器(koa框架)通信及服务器跨域配置详解
2017/08/26 Javascript
原生JS实现DOM加载完成马上执行JS代码的方法
2018/09/07 Javascript
layui 对弹窗 form表单赋值的实现方法
2019/09/04 Javascript
Vue 2.0双向绑定原理的实现方法
2019/10/23 Javascript
[01:09:13]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第三场 1月19日
2021/03/11 DOTA
python利用Guetzli批量压缩图片
2017/03/23 Python
python 猴子补丁(monkey patch)
2019/06/26 Python
Django中create和save方法的不同
2019/08/13 Python
Python Django中间件,中间件函数,全局异常处理操作示例
2019/11/08 Python
tensorflow tf.train.batch之数据批量读取方式
2020/01/20 Python
Python接口自动化判断元素原理解析
2020/02/24 Python
python 6行代码制作月历生成器
2020/09/18 Python
九月份红领巾广播稿
2014/01/22 职场文书
生产部厂长职位说明书
2014/03/03 职场文书
公司承诺书怎么写
2014/05/24 职场文书
机械设备与数控技术专业求职信
2014/08/10 职场文书
二手房购房协议书范本
2014/10/05 职场文书
开学第一周日记(三篇范文)
2019/08/23 职场文书
go:垃圾回收GC触发条件详解
2021/04/24 Golang