Scrapy与Python:DNS查找失败,配置代理后仍无法正常运行?
解决Scrapy在公司代理环境下的DNS解析失败问题
你遇到的核心问题是公司网络强制要求通过代理访问外部资源,直接在Request里加代理的思路是对的,但可能代理格式或者全局配置没做好,我给你几个靠谱的解决办法:
一、修正Request中的代理格式
你当前写的request.meta['proxy'] = "user@proxy:port"格式不对,正确的代理格式要区分是否需要认证:
- 如果代理不需要用户名密码:
http://proxy_ip:port - 如果代理需要认证:
http://username:password@proxy_ip:port
把这行改成正确格式,比如:
request.meta['proxy'] = "http://your_username:your_password@company_proxy:port"
(记得替换成你公司实际的代理地址、端口和认证信息)
二、全局配置代理(更省心,不用每个Request都加)
如果你的爬虫所有请求都需要走代理,更推荐在Scrapy的settings.py里全局配置,这样不用在代码里重复写:
- 打开项目的
settings.py文件 - 添加以下配置:
# 代理地址(带认证的格式) HTTP_PROXY = "http://username:password@proxy_ip:port" HTTPS_PROXY = "http://username:password@proxy_ip:port" # 若不需要认证,就写成: # HTTP_PROXY = "http://proxy_ip:port" # HTTPS_PROXY = "http://proxy_ip:port" # 开启代理中间件(默认关闭,需要手动打开) DOWNLOADER_MIDDLEWARES = { 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110, }
这样所有请求都会自动走代理,不用在start_requests里手动加meta['proxy']了。
三、额外排查点
- 验证代理可用性:先在终端用
curl测试代理是否能正常访问目标网站,比如:
curl -x http://username:password@proxy_ip:port http://quotes.toscrape.com
如果curl能拿到内容,说明代理没问题,那就是Scrapy的配置问题;如果curl也失败,得找公司IT确认代理地址、端口和认证信息是否正确。
2. DNS解析辅助配置:有些公司网络下,代理会处理DNS解析,你可以在settings.py里添加:
DNS_RESOLVER = 'scrapy.resolver.CachingHostnameResolver'
不过一般来说,只要代理配置正确,这个不是必须的。
测试修改后的代码
如果用全局配置,你的爬虫代码可以简化回官方教程的样子:
import scrapy class QuotesSpider(scrapy.Spider): name = "quotes" start_urls = [ 'http://quotes.toscrape.com/page/1/', 'http://quotes.toscrape.com/page/2/', ] def parse(self, response): page = response.url.split("/")[-2] filename = 'quotes-%s.html' % page with open(filename, 'wb') as f: f.write(response.body) self.log('Saved file %s' % filename)
按照上面的步骤来,应该就能解决DNS解析失败的问题了,优先从代理格式和全局配置入手,这是最常见的解决方式。
内容的提问来源于stack exchange,提问作者Cactus
相关产品推荐
相关产品推荐

