一、系统代理

代理控制出站和进站顺序(出是先经过代理然后下载器,入相反)

1、优先级控制出站和进站顺序(出是先经过代理然后下载器,入相反)

scrapy crawl httpbin --nolog 

–nolog : 不打印日志信息


系统代理

1、配置代理所有的http请求将由我们指定的ip和port出去(linux&mac)

export http_proxy='http://*.*.*.*:80'  

这只是临时修改,永久修改需要修改配置文件。


2、更改settings.py配置文件(取消注释并增加scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware

DOWNLOADER_MIDDLEWARES = {
    'proxyspider.middlewares.ProxyspiderDownloaderMiddleware': 543,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 400,
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': 400, #去掉不影响
}

优先级由后面的数字大小(数字越小越优先)决定,改为None临时不生效。


在Windows里面按着Ctrl键,点击scrapy

在这里插入图片描述


点击箭头方向的scrapy,在下拉列表中找到downloadermiddlewares,再点击httpproxy

在这里插入图片描述


最后我们就到了httpproxy.py这个文件里面,这里面有我们需要的方法。

在这里插入图片描述

HttpProxyMiddleware会加载系统的环境变量,把我们设置的代理设置到scrapy上面。以上两个步骤就实现了系统代理的设置。

下载中间件有很多种设置代理只是其中的一个使用方法,设置系统代理的方法很简单,总结起来就是更改settings配置,加上我们需要的下载中间件,给上优先级然后设置系统代理就可以了。



二、自定义中间件&随机代理

1、settings.py

增加如下内容:

DOWNLOADER_MIDDLEWARES = {
    'proxyspider.middlewares.ProxyspiderDownloaderMiddleware': 543,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None,
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
    'proxyspider.middlewares.RandomHttpProxyMiddleware': 400,  #自定义的方法位置
}

#取值列表我们需要的代理ip按照这个格式写到下面,配置项尽量大写。
HTTP_PROXY_LIST = [
     'http://52.179.231.206:80',
     'http://95.0.194.241:9090',
]

2、在middlewares中编写RandomHttpProxyMiddleware方法

在这里插入图片描述

(1)提前导入一下库

from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware #导入系统的代理的类,我们需要继承这个类,来重写。
from scrapy.exceptions import NotConfigured          #抛错用到的库,为了和系统代理的配置一样。
from collections import defaultdict                  #defaultdict
from urllib.parse import urlparse                    #可以把 'http://52.179.231.206:80'分成协议和IP
import random                                        #用来随机取值

(2)实现代码

from scrapy import signals
from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware
from scrapy.exceptions import NotConfigured
from collections import defaultdict
from urllib.parse import urlparse
import random

class RandomHttpProxyMiddleware(HttpProxyMiddleware):

    def __init__(self, auth_encoding='utf-8', proxy_list = None):
        self.proxies = defaultdict(list)
        for proxy in proxy_list:
            parse = urlparse(proxy)
            self.proxies[parse.scheme].append(proxy)

    @classmethod
    def from_crawler(cls, crawler):
        if not crawler.settings.get('HTTP_PROXY_LIST'):
            raise NotConfigured

        http_proxy_list = crawler.settings.get('HTTP_PROXY_LIST')  
        auth_encoding = crawler.settings.get('HTTPPROXY_AUTH_ENCODING', 'utf-8')

        return cls(auth_encoding, http_proxy_list)

    def _set_proxy(self, request, scheme):
        proxy = random.choice(self.proxies[scheme])
        request.meta['proxy'] = proxy

代码注解:

from_crawler

因为 @classmethod(装饰器)的存在,所以from_crawler是类的方法,它会直接被调用,首先if判断settings配置文件里面是否有我们要的配置项,然后下面就是去这个配置项,并return。return调用了cls也就是类本身并传入了参数,类本身的参数有默认值,实际上我们只传入http_proxy_list就可以了。


__init__

接收来自from_crawler的参数,self.proxies定义一个字典,然后把IP取出来,urlparse会把ip和协议分开,然后把结果保存到self.proxies


_set_proxy

最后_set_proxy会把我们的ip设置到系统上面。scheme是我们要传入的参数,传入的是协议。random随机取值。


在代码中加入print查看输出

在这里插入图片描述

Logo

更多推荐