如何正确配置scrapy-proxies与Scrapy使代理正常生效?
问题描述
我在项目中使用了scrapy-proxies与scrapy-fake-useragent组件,但发起的请求并未通过代理转发,仍然走本地公网IP地址。
我的settings.py配置文件内容如下:
BOT_NAME = 'scraper' SPIDER_MODULES = ['scraper.spiders'] NEWSPIDER_MODULE = 'scraper.spiders' REACTOR_THREADPOOL_MAXSIZE = 5 DOWNLOAD_TIMEOUT = 30 ROBOTSTXT_OBEY = True RETRY_TIMES = 10 RETRY_HTTP_CODES = [500, 503, 504, 400, 403, 404, 408] DOWNLOADER_MIDDLEWARES = { 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, 'scrapy.downloadermiddlewares.retry.RetryMiddleware': None, 'scrapy_proxies.RandomProxy': 100, 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110, 'scrapy_fake_useragent.middleware.RandomUserAgentMiddleware': 200, 'scrapy_fake_useragent.middleware.RetryUserAgentMiddleware': 201, } PROXY_LIST = 'proxies.txt' PROXY_MODE = 0 FAKEUSERAGENT_PROVIDERS = [ 'scrapy_fake_useragent.providers.FakeUserAgentProvider', 'scrapy_fake_useragent.providers.FakerProvider', 'scrapy_fake_useragent.providers.FixedUserAgentProvider', ] USER_AGENT ='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36' RANDOM_UA_PER_PROXY = True DOWNLOADER_CLIENT_TLS_METHOD = "TLSv1.2" ITEM_PIPELINES = { 'scraper.pipelines.CsvWriterPipeline': 600 }
我已经尝试调整DOWNLOADER_MIDDLEWARES配置项中各中间件的优先级,但问题仍然没有解决,请问当前配置存在哪些错误?
配置错误排查与修正
你的配置存在4个直接导致代理不生效的问题,按影响优先级排序:
- 缺失代理组件配套的重试中间件
你直接将Scrapy默认的RetryMiddleware设为禁用,但没有启用scrapy-proxies配套的重试切换逻辑。当选中的代理连接失败、返回重试状态码时,框架不会自动切换到新代理,甚至会直接绕开代理发起本地请求。 - 代理列表文件路径配置错误
你当前用相对路径proxies.txt指定代理文件,Scrapy运行时的工作目录和项目根目录不一致时(比如从其他目录执行启动命令),会直接读取不到代理列表。读取失败时scrapy-proxies不会抛出阻断错误,仅打印警告后跳过所有代理设置,请求默认走本地IP。 - 代理列表格式不符合解析要求
scrapy-proxies要求代理文件中每一行必须明确标注协议前缀,无协议头的ip:port格式会被直接忽略,不会绑定到请求上。合法格式示例:
如果使用SOCKS5代理,需要提前安装socks支持依赖。http://127.0.0.1:8888 http://user:password@127.0.0.1:8888 socks5://127.0.0.1:1080 - 中间件执行顺序冲突
你当前将RetryUserAgentMiddleware优先级设为201,但没有把重试中间件放在它之前执行,会导致重试时既不会切换代理也不会切换UA。另外你手动设置了固定USER_AGENT值,且UA提供者列表中包含FixedUserAgentProvider,会导致随机UA功能失效(该问题不影响代理转发,仅影响UA随机效果)。
修正后的参考配置
from pathlib import Path BOT_NAME = 'scraper' SPIDER_MODULES = ['scraper.spiders'] NEWSPIDER_MODULE = 'scraper.spiders' REACTOR_THREADPOOL_MAXSIZE = 5 DOWNLOAD_TIMEOUT = 30 ROBOTSTXT_OBEY = True RETRY_TIMES = 10 RETRY_HTTP_CODES = [500, 503, 504, 400, 403, 404, 408] DOWNLOADER_MIDDLEWARES = { 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, # 保留默认重试中间件,调整优先级到代理中间件之前 'scrapy.downloadermiddlewares.retry.RetryMiddleware': 90, 'scrapy_proxies.RandomProxy': 100, 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110, 'scrapy_fake_useragent.middleware.RandomUserAgentMiddleware': 400, 'scrapy_fake_useragent.middleware.RetryUserAgentMiddleware': 401, } # 替换为基于settings文件的绝对路径,避免路径读取失败 PROXY_LIST = str(Path(__file__).parent / 'proxies.txt') PROXY_MODE = 0 FAKEUSERAGENT_PROVIDERS = [ 'scrapy_fake_useragent.providers.FakeUserAgentProvider', 'scrapy_fake_useragent.providers.FakerProvider', 'scrapy_fake_useragent.providers.FixedUserAgentProvider', ] # 不需要随机UA可以保留固定USER_AGENT,需要随机则注释掉下面这行 # USER_AGENT ='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36' RANDOM_UA_PER_PROXY = True DOWNLOADER_CLIENT_TLS_METHOD = "TLSv1.2" ITEM_PIPELINES = { 'scraper.pipelines.CsvWriterPipeline': 600 }
排查小技巧:启动爬虫时加
--loglevel=DEBUG参数,观察日志中是否有Ignoring response、Cannot load proxy list相关警告,可快速定位是文件读取失败还是代理格式错误。
内容的提问来源于stack exchange,提问作者Sam Quinn
相关产品推荐
相关产品推荐

