写一个scrapy中间件--ip代理池
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代理池的更多相关文章
- [爬虫]一个易用的IP代理池
一个易用的IP代理池 - stand 写爬虫时常常会遇到各种反爬虫手段, 封 IP 就是比较常见的反爬策略 遇到这种情况就需要用到代理 IP, 好用的代理通常需要花钱买, 而免费的代理经常容易失效, ...
- python爬虫实战(三)--------搜狗微信文章(IP代理池和用户代理池设定----scrapy)
在学习scrapy爬虫框架中,肯定会涉及到IP代理池和User-Agent池的设定,规避网站的反爬. 这两天在看一个关于搜狗微信文章爬取的视频,里面有讲到ip代理池和用户代理池,在此结合自身的所了解的 ...
- Scrapy学习-13-使用DownloaderMiddleware设置IP代理池及IP变换
设置IP代理池及IP变换方案 方案一: 使用国内免费的IP代理 http://www.xicidaili.com # 创建一个tools文件夹,新建一个py文件,用于获取代理IP和PORT from ...
- Scrapy加Redis加IP代理池实现音乐爬虫
音乐爬虫 关注公众号"轻松学编程"了解更多. 目的:爬取歌名,歌手,歌词,歌曲url. 一.创建爬虫项目 创建一个文件夹,进入文件夹,打开cmd窗口,输入: scrapy star ...
- 爬取西刺ip代理池
好久没更新博客啦~,今天来更新一篇利用爬虫爬取西刺的代理池的小代码 先说下需求,我们都是用python写一段小代码去爬取自己所需要的信息,这是可取的,但是,有一些网站呢,对我们的网络爬虫做了一些限制, ...
- scrapy_随机ip代理池
什么是ip代理? 我们电脑访问网站,其实是访问远程的服务器,通过ip地址识别是那个机器访问了服务器,服务器就知道数据该返回给哪台机器,我们生活中所用的网络是局域网,ip是运营商随机分配的,是一种直接访 ...
- ip代理池的爬虫编写、验证和维护
打算法比赛有点累,比赛之余写点小项目来提升一下工程能力.顺便陶冶一下情操 本来是想买一个服务器写个博客或者是弄个什么FQ的东西 最后刷知乎看到有一个很有意思的项目,就是维护一个「高可用低延迟的高匿IP ...
- 记一次企业级爬虫系统升级改造(六):基于Redis实现免费的IP代理池
前言: 首先表示抱歉,春节后一直较忙,未及时更新该系列文章. 近期,由于监控的站源越来越多,就偶有站源做了反爬机制,造成我们的SupportYun系统小爬虫服务时常被封IP,不能进行数据采集. 这时候 ...
- Python爬虫之ip代理池
可能在学习爬虫的时候,遇到很多的反爬的手段,封ip 就是其中之一. 对于封IP的网站.需要很多的代理IP,去买代理IP,对于初学者觉得没有必要,每个卖代理IP的网站有的提供了免费IP,可是又很少,写了 ...
随机推荐
- OpenSSL之X509系列
OpenSSL之X509系列之1---引言和X509概述 [引言] X509是系列的函数在我们开发与PKI相关的应用的时候我们都会用到,但是OpenSSL中对X509的描述并不是很多,鉴于些,我 ...
- 吴裕雄--天生自然 PYTHON数据分析:基于Keras的CNN分析太空深处寻找系外行星数据
#We import libraries for linear algebra, graphs, and evaluation of results import numpy as np import ...
- O2O疯狂烧钱路:止血还是放血好
在国内,无论是互联网巨头还是创业者,很多都将O2O领域当做下一个金矿.而对于很多O2O项目来说,市场规模.用户基数.发展潜力等传统指数依然被当做硬性指标.而为了抢夺用户,很多O2O项目都只能疯狂烧钱, ...
- 点击穿透bug · Jaywii
微信点击穿透Bug 问题描述:在移动端为了去除点击延迟引入了fast-click,然而在房贷计算器的开发中遇到了这样一个bug,用户点击了select之后,微信在弹出选择器之后会瞬间因为约300ms的 ...
- uboot--tftp
一. 概述 U-boot中的TFTP用于发送较小的文件.下层使用UDP协议,发送使用UDP 69端口,每次发送的最大分组为512 Bytes.发送双方采用超时重传机制.数据传输模式为octe ...
- linux入门系列16--文件共享之Samba和NFS
前一篇文章"linux入门系列15--文件传输之vsftp服务"讲解了文件传输,本篇继续讲解文件共享相关知识. 文件共享在生活和工作中非常常见,比如同一团队中不同成员需要共同维护同 ...
- 有了这个开源 Java 项目,开发出炫酷的小游戏好像不难?
本文适合有 Java 基础知识的人群,跟着本文可学习和运行 Java 的游戏. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列,今天给大家带来一 ...
- java 初探-猜数字
学习Java而编写的猜数字的程序代码. /** * */ package org.literal.test; import java.util.Scanner; /** * @author liter ...
- VUE实现Studio管理后台(一):鼠标拖放改变窗口大小
近期改版RXEditor,把改版过程,用到的技术点,记录下来.昨天完成了静态页面的制作,制作过程并未详细记录,后期已经不愿再补了,有些遗憾.不过工作成果完整保留在github上,地址:https:// ...
- 关于localStorage面试的那点事
最近面试的时候关于html5API总会被问到localStorage的问题, 对于一般的问题很简单,无非就是 localStorage.sessionStorage和cookie这三个客户端缓存的区别 ...