Python中关于Scrapy框架使用代理IP的问题

同样的代理 IP,我用 requests 时可以正常访问,用 scrapy 写中间件结果却是 10060 和 10061
requests 代码
def get_urls(url=START_URL):
proxies = {“http”: “http://{}”.format(“1.28.91.229:61202”)}
print(proxies)
r = requests.get(url, proxies=proxies, headers=DEFAULT_REQUEST_HEADERS)
etree = lxml.html.fromstring(r.text)
# 获取界面关注人的路径
urls = etree.xpath("//dl[@class=‘obu’]/dd/a/@href")
print(urls)

中间件这样写的
class ProxyMiddleware(object):
‘’‘设置代理 IP’’’

def process_request(self, request, spider):
pro_adr = random.choice(PROXIES)
print("USE PROXY -> " + pro_adr)
request.meta[“proxy”] = “http://” + pro_adr.strip()
Python中关于Scrapy框架使用代理IP的问题


2 回复

在Scrapy里用代理IP,核心就两件事:设置代理中间件和处理好认证。

1. 基础设置(无需认证的代理) 最简单的方法是在 settings.py 里加个下载器中间件,然后在爬虫的 start_requests 或请求里塞代理。看代码:

# settings.py
DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 400,
}

# 你的爬虫文件
import scrapy

class MySpider(scrapy.Spider):
    name = 'my_spider'
    start_urls = ['http://example.com']

    def start_requests(self):
        proxy = "http://123.45.67.89:8080" # 替换成你的代理IP和端口
        for url in self.start_urls:
            yield scrapy.Request(url, meta={'proxy': proxy}, callback=self.parse)

    def parse(self, response):
        # 你的解析逻辑
        pass

2. 需要认证的代理(推荐方法) 大部分收费代理都要认证。更靠谱的做法是写个自定义中间件,把认证信息拼到代理URL里。在项目里新建个 middlewares.py

# middlewares.py
class ProxyMiddleware(object):
    def process_request(self, request, spider):
        # 格式:http://user:pass@ip:port
        proxy = "http://your_username:your_password@123.45.67.89:8080"
        request.meta['proxy'] = proxy

然后在 settings.py 里启用它,并设置优先级(数字越小越先执行):

# settings.py
DOWNLOADER_MIDDLEWARES = {
    'your_project.middlewares.ProxyMiddleware': 543, # 优先级数字自己定,别冲突就行
}

3. 动态代理池 如果代理IP经常变或者要轮换,可以在中间件里从文件、数据库或API动态获取。比如从 proxies.txt 里随机选一个:

# middlewares.py
import random

class RotatingProxyMiddleware(object):
    def __init__(self):
        with open('proxies.txt', 'r') as f:
            self.proxies = [line.strip() for line in f]

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

关键点总结

  • 普通代理直接设 meta['proxy']
  • 需要认证就把用户名密码放到URL里(http://user:pass@ip:port)。
  • 用中间件方式更灵活,方便管理轮换和异常。
  • 记得处理代理失效的情况,好的爬虫得有点容错能力。

一句话建议:写个代理中间件,把认证信息拼到URL里最省事。


代理失效了吧,换个代理试试

回到顶部