middleware文件

# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/spider-middleware.html import random
from scrapy import signals class TutorialDownloaderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects. @classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware. # Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
return None def process_response(self, request, response, spider):
# Called with the response returned from the downloader. # Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception. # Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name) # 创建一个中间件 ip代理池
from collections import defaultdict
from scrapy.exceptions import NotConfigured
class RandomProxyMiddleware(object): def __init__(self, settings):
# 第三步 初始化配置和变量
# 在settings中写一个 PROXIES 列表配置
# 从settings中把代理读进来(把环境变量读进来)
self.proxies = settings.getlist("PROXIES")
self.stats = defaultdict(int) # 默认值是0 统计次数
self.max_failed = 3 # 请求最多不超过3次 @classmethod
def from_cralwer(cls, crawler):
# 第一步 创建中间件对象
# 首先获取配置 HTTPPROXY_ENABLED 看看是否启用代理,
if not crawler.settings.getbool("HTTPPROXY_ENABLED"): # 如果没有启用代理
raise NotConfigured
# auth_encoding = crawler.settings.get("HTTPPROXY_AUTH_ENCODING") # 读取配置,这里暂时不用
# 第二步
return cls(crawler.settings) # cls()实际调用的是 init()函数,如果init接受参数,cls就需要参数 def process_request(self, request, spider):
# 第四步 为每个request对象随机分配一个ip代理
# 让这个请求使用代理 初始url不使用代理ip
if self.proxies and not request.meta.get("proxy") and request.url not in spider.start_urls:
request.meta["proxy"] = random.choice(self.proxies)
       def process_response(self, request, response, spider):
# 第五步: 请求成功
cur_proxy = request.meta.get('proxy')
# 判断是否被对方禁封
if response.status > 400:
# 给相应的ip失败次数 +1
self.stats[cur_proxy] += 1
print("当前ip{},第{}次出现错误状态码".format(cur_proxy, self.stats[cur_proxy]))
# 当某个ip的失败次数累计到一定数量
if self.stats[cur_proxy] >= self.max_failed: # 当前ip失败超过3次
print("当前状态码是{},代理{}可能被封了".format(response.status, cur_proxy))
# 可以认为该ip被对方封了,从代理池中删除这个ip
self.remove_proxy(cur_proxy)
del request.meta['proxy']
# 将这个请求重新给调度器,重新下载
return request # 状态码正常的时候,正常返回
return response def process_exception(self, request, exception, spider):
# 第五步:请求失败
cur_proxy = request.meta.get('proxy') # 取出当前代理
from twisted.internet.error import ConnectionRefusedError, TimeoutError
# 如果本次请求使用了代理,并且网络请求报错,认为这个ip出了问题
if cur_proxy and isinstance(exception, (ConnectionRefusedError, TimeoutError)):
print("当前的{}和当前的{}".format(exception, cur_proxy))
self.remove_proxy(cur_proxy)
del request.meta['proxy']
# 重新下载这个请求
return request def remove_proxy(self, proxy):
if proxy in self.proxies:
self.proxies.remove(proxy)
print("从代理列表中删除{}".format(proxy))
settings 文件

# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
'tutorial.middlewares.RandomProxyMiddleware': 749, # 修改下载优先级数字
}

写一个scrapy中间件--ip代理池的更多相关文章

  1. [爬虫]一个易用的IP代理池

    一个易用的IP代理池 - stand 写爬虫时常常会遇到各种反爬虫手段, 封 IP 就是比较常见的反爬策略 遇到这种情况就需要用到代理 IP, 好用的代理通常需要花钱买, 而免费的代理经常容易失效, ...

  2. python爬虫实战(三)--------搜狗微信文章(IP代理池和用户代理池设定----scrapy)

    在学习scrapy爬虫框架中,肯定会涉及到IP代理池和User-Agent池的设定,规避网站的反爬. 这两天在看一个关于搜狗微信文章爬取的视频,里面有讲到ip代理池和用户代理池,在此结合自身的所了解的 ...

  3. Scrapy学习-13-使用DownloaderMiddleware设置IP代理池及IP变换

    设置IP代理池及IP变换方案 方案一: 使用国内免费的IP代理 http://www.xicidaili.com # 创建一个tools文件夹,新建一个py文件,用于获取代理IP和PORT from ...

  4. Scrapy加Redis加IP代理池实现音乐爬虫

    音乐爬虫 关注公众号"轻松学编程"了解更多. 目的:爬取歌名,歌手,歌词,歌曲url. 一.创建爬虫项目 创建一个文件夹,进入文件夹,打开cmd窗口,输入: scrapy star ...

  5. 爬取西刺ip代理池

    好久没更新博客啦~,今天来更新一篇利用爬虫爬取西刺的代理池的小代码 先说下需求,我们都是用python写一段小代码去爬取自己所需要的信息,这是可取的,但是,有一些网站呢,对我们的网络爬虫做了一些限制, ...

  6. scrapy_随机ip代理池

    什么是ip代理? 我们电脑访问网站,其实是访问远程的服务器,通过ip地址识别是那个机器访问了服务器,服务器就知道数据该返回给哪台机器,我们生活中所用的网络是局域网,ip是运营商随机分配的,是一种直接访 ...

  7. ip代理池的爬虫编写、验证和维护

    打算法比赛有点累,比赛之余写点小项目来提升一下工程能力.顺便陶冶一下情操 本来是想买一个服务器写个博客或者是弄个什么FQ的东西 最后刷知乎看到有一个很有意思的项目,就是维护一个「高可用低延迟的高匿IP ...

  8. 记一次企业级爬虫系统升级改造(六):基于Redis实现免费的IP代理池

    前言: 首先表示抱歉,春节后一直较忙,未及时更新该系列文章. 近期,由于监控的站源越来越多,就偶有站源做了反爬机制,造成我们的SupportYun系统小爬虫服务时常被封IP,不能进行数据采集. 这时候 ...

  9. Python爬虫之ip代理池

    可能在学习爬虫的时候,遇到很多的反爬的手段,封ip 就是其中之一. 对于封IP的网站.需要很多的代理IP,去买代理IP,对于初学者觉得没有必要,每个卖代理IP的网站有的提供了免费IP,可是又很少,写了 ...

随机推荐

  1. String的compareTo用法

    String的compareTo其实就是依次比较两个字符串ASC码.如果两个字符的ASC码相等则继续后续比较,否则直接返回两个ASC的差值.如果两个字符串完全一样,则返回0.来看一下代码. publi ...

  2. Java IO: 其他字符流(下)

    作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) 本小节会简要概括Java IO中的PushbackReader,LineNumberReader,St ...

  3. python3多线程爬虫(第一卷)

    多进程虽然使用方便,可以充分利用CPU,但是由于个进程之间是并行且各自有自己的数据存储,所以很难进行数据间的通信,需要接入第三方模块,现在我依旧用糗事百科讲解下多线程的应用,举个例子之前用4个进程同时 ...

  4. SSM 生成mapper中xml文件:未能解析映射资源:“文件嵌套异常

    错误日记我就网上随便找个贴着: 错误一: org.springframework.beans.factory.BeanCreationException: Error creating bean wi ...

  5. 饿了么vue实现学习笔记

    技术栈:vue2 + vuex + vue-router + webpack + ES6/7 + fetch + sass + flex + svg以功能实现着手学习1. 定位功能 home.vue ...

  6. MyBatis基本使用步骤

    MyBatis是一个数据持久层(ORM)框架.把实体 类和SQL语句之间建立了映射关系,是一种半自 动化的ORM实现.MyBATIS需要开发人员自己来写sql语句,这可以增加了程序的灵活性,在一定程度 ...

  7. JavaScript深入浅出-闭包

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 function (){ var localVal ...

  8. centos7系统盘变为只读文件的修复

    一台物理机的系统盘在磁盘空间有剩余的情况下变为只读了,咨询后发现前几日修改过系统,然后就不可写了,重启也不行.见下图 解决:参考链接https://bbs.51cto.com/thread-92640 ...

  9. python基础函数、方法

    python的函数和方法,通过def 定义: 函数的特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 函数和方法的区别:函数有返回值.方法没有 语法定义: def sayhi():#函数名 p ...

  10. Leetcode-Day Three

    1002. Find Common Characters Given an array A of strings made only from lowercase letters, return a ...