scrapy框架设置代理的两种方式

  使用scrapy框架编写爬虫程序时与直接使用requests包的不同点就在于:scrapy是封装之后的requests很多的功能以及设置都已经默认封装好了,有一些基本的设置直接可以在setting文件中修改,而且创建多个爬虫也非常的方便,但是对于对scrapy框架了解没那么深入的人,想要修改稍微复杂一点的功能又非常的困难(我记得我刚开始做爬虫的时候就是采取scrapy与requests相结合的方法,在一些需要复杂设置的时候scrapy找不到该怎么改,就用requests写功能函数实现,这种方法虽然能实现,但是脱离了使用框架的意义),那么我们就来慢慢的细数scrapy中的稍微复杂的操作以及设置。

一:在middlewares(中间件)中添加ip代理

(1).外部维护的代理池

  由于操作与上面的方法有很多类似,所以只介绍理论部分。代码可以从方法(2)中参考
  如果你有其他的程序在某个地方,比如mysql数据库中维护了一个可以使用的代理池,那么在中间件中就可以直接封装一个类,随机查询mysql中的某个代理,在封装的类中设置一个scrapy默认在发送url给下载器之前调用的函数process_request(self, request, spider), 默认会有这三个参数,然后在最后添加request.meta[“proxy”] = 你的ip, 这样就可以将代理ip添加到请求中。
  但是这种方法有一定的缺陷:假设你的代理池很小,在某一段时间之内,你抽到了同一个ip多次,故而被网站封掉了这次ip,但是维护程序在其他的网站验证时,这个ip还是可使用的,就造成了这个ip一直存在库中,但是对你现在想要抓取的网站已经没有了作用,这时有两个方法可以解决:
  1.扩大代理池,使同一段时间内抽到同一个代理的概率变小,或者设置一个判断:只从数据库中几分钟内没有被抽中的代理中抽取。
  2.开启retry功能,此功能可以直接在settings文件中设置

HTTPERROR_ALLOWED_CODES = [404, 403, 301, 500, 407]  
# 出现这些状态码会重复进行请求
# DOWNLOAD_TIMEOUT = 3  # 设置超时参数 秒
RETRY_ENABLED = True  # 是否开启 retry功能
RETRY_TIMES = 20  # retry的次数

  可以根据具体情况设置retry的次数和超时时间。
  当然在真正的使用代理池时,因为我们需要发送的请求一般都是千万或者亿级的,就算是很小的概率还是有可能造成当次请求的失败。
我一直在使用的一个代理验证的网站,可以验证使用代理成没成功,并且还可以验证代理的“好坏”程度
    http://fetch.bestzsj.com/v1/validate_ip_https

(2)跟随scrapy框架随时用随时使用的代理池

  在工作中,如果我们不经常使用代理池,假如一个月才有两天的时间使用代理池,那该怎么办?我们并不想维护着数据库中的代理池的程序一直运行着,但是随用随开启维护程序的话,刚开始的池又太小。对这种情况那该怎么办?
  对于这种对不需要一直维护代理池的情况,可以在程序中设置维护代理池的程序,随着爬虫的启动而进行维护。
  优点在于:在使用代理时被封的代理可以立即剔除,不需要一直维护数据库中的代理池。
  缺点在于:在运行时会使用很多不可使用的代理,这时候要设置retry的次数要增大,耗费的时间相比于第一种方法要多一点。
上代码:
  middlewares


# 本次测试根据ip的可用性改变ip列表的长度
class ProxyMiddleware2(object):
    """
    过滤全部ip中不能用的ip时
        1.首先可以使用一个简单网站先验证这个ip是不是有效的
        2.1有效的ip在请求具体网站的时候也会出现 不能使用的情况,这时过滤到刚开始就直接连接不上的ip
        2.2 到此时所有的ip都是可用的, 但是也会出现在使用的过程中某个ip的调用太过频繁而被封锁的情况, 也进行删除
        3.当ip列表的长度到达一个临界点时 进行重新获取新的ip列表
    """
    def __init__(self):

        self.ip_list = []

    def process_request(self, request, spider):

        while True:
            if len(self.ip_list) < 3:  # 设定代理ip的列表 小于某一个值时重新获取ip 并验证
                self.get_ip()
            else:
                break

        ip_raw = random.choice(self.ip_list)

        self.ip_list.remove(ip_raw)

        request.meta['download_timeout'] = 5
        print("本次使用的ip:", ip_raw, "*"*10)
        request.meta["proxy"] = ip_raw

    def get_ip(self):
        
        url = "你的代理的获取地址"
        
        # 我在这里使用的是云代理的api,解析也是云代理返回的数据的解析,如果不一样则修改下面的代码
        r = requests.get(url).json()

        for r_one in r:
            ip_one = "http://" + r_one["Ip"] + ":" + str(r_one["Port"])
            self.ip_list.append(ip_one)

    def process_response(self, request, response, spider):
        self.ip_list.append(request.meta["proxy"])

        print("代理池目前的大小为:", len(self.ip_list), " ############")
        return response

  完成代理的逻辑之后就可以在settings中将此中间件开启
settings中的设置
  设置完成之后,可以使用上面的验证网站进行验证,给请求添加代理也就完成了。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Scrapy设置代理需要通过 middleware 来实现。以下是一个简单的隧道代理设置示例: 1. 创建一个自定义的 middleware,命名为 `RandomProxyMiddleware`,并将其添加Scrapy 的 settings.py 中: ```python from scrapy import signals import random class RandomProxyMiddleware(object): def __init__(self, settings): self.proxies = settings.getlist('PROXIES') @classmethod def from_crawler(cls, crawler): return cls(crawler.settings) def process_request(self, request, spider): request.meta['proxy'] = random.choice(self.proxies) ``` 2. 在 settings.py 中添加以下配置: ```python PROXIES = [ 'http://user:password@proxy1.example.com:8080', 'http://user:password@proxy2.example.com:8080', # ... ] DOWNLOADER_MIDDLEWARES = { 'myproject.middlewares.RandomProxyMiddleware': 543, 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 544, } ``` 在这个示例中,我们创建了一个自定义的 middleware `RandomProxyMiddleware`,它会从 `PROXIES` 列表中随机选择一个代理,并将其设置为 request 的 meta 属性中的 `proxy` 字段。同时,我们还将 Scrapy 自带的 `HttpProxyMiddleware` 添加到了 middleware 列表中,以便 Scrapy 使用我们设置代理。最后,我们将这两个 middleware 的优先级分别设置为 543 和 544,以确保 `RandomProxyMiddleware` 先于 `HttpProxyMiddleware` 执行。 3. 运行 Scrapy 爬虫时,所有的请求都会通过 `RandomProxyMiddleware` 中设置代理进行发送。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jingjiadashaoye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值