分享页面
技术分享 / 2026年Python数据抓取配置代理IP的4种方法

2026年Python数据抓取配置代理IP的4种方法

技术分享

我们青果网络长期服务网站采集器、招投标数据这类公开数据采集业务,实践中反复看到:真正影响运行质量的不是哪一行语法,而是代理存活周期、并发模型和请求节奏是否匹配。

代理参数填对了,为什么任务还是不稳?

代理IP接入的判断顺序应该是授权、连通、复用、切换,不能只看请求是否返回成功。一次测试能返回页面,只能证明当时的地址可连接,不能证明它适合长任务、并发任务或固定会话。

上线前先确认4项输入:

输入 应该确认什么 常见处理
代理地址 主机、端口、协议是否匹配 使用控制台或提取接口返回的真实代理地址
验证方式 白名单还是账密 固定服务器优先白名单,环境变化频繁时使用账密
存活周期 单个IP可使用多久 缓存截止时间,提前刷新,不把失效地址留给下一批任务
业务节奏 单次、批量、并发还是框架任务 分别选择requests、urllib、aiohttp或Scrapy

青果网络支持HTTP、HTTPS、SOCKS5协议,验证方式可选白名单或账密,终端数不限制,白名单数量为256个(来源:青果网络官网)。进入代理IP提取工具后,应记录返回结果里的server字段,它才是代码需要使用的代理地址。proxy_ip是实际出口IP,request_id用于定位接口调用问题(来源:青果网络官网)。需要按任务量评估资源时,可同时查看国内短效代理的存活周期、提取上限和验证方式。

下面的示例统一使用HTTP代理连接HTTPS目标。账号、密码和地址都从环境变量读取,避免把凭据写进仓库。测试目标只是公开的出口查询接口,正式采集前仍需确认数据授权范围、站点协议和访问频次要求。

export QG_PROXY_HOST="127.0.0.1"
export QG_PROXY_PORT="8080"
export QG_PROXY_USER="your_auth_key"
export QG_PROXY_PASS="your_auth_password"

如果使用白名单验证,可不设置QG_PROXY_USER和QG_PROXY_PASS。先在控制台把运行机器的公网IP加入白名单,再执行代码。

方法一:单次请求怎么用requests配置代理IP?

临时测试、低频接口采集和连通性验证,直接给requests.get传入proxies最清楚。这类写法没有隐式状态,适合先确认协议、鉴权和出口是否正确。

先安装依赖:

python -m pip install requests

完整代码如下:

import os
from urllib.parse import quote

import requests


def build_proxy_url() -> str:
    host = os.environ["QG_PROXY_HOST"]
    port = os.environ["QG_PROXY_PORT"]
    user = os.getenv("QG_PROXY_USER")
    password = os.getenv("QG_PROXY_PASS")

    if user and password:
        safe_user = quote(user, safe="")
        safe_password = quote(password, safe="")
        return f"http://{safe_user}:{safe_password}@{host}:{port}"
    return f"http://{host}:{port}"


def main() -> None:
    proxy_url = build_proxy_url()
    proxies = {
        "http": proxy_url,
        "https": proxy_url,
    }

    response = requests.get(
        "https://httpbin.org/ip",
        proxies=proxies,
        timeout=(5, 15),
    )
    response.raise_for_status()
    print(response.json())


if __name__ == "__main__":
    main()

这段代码有3个值得保留的细节:

  • quote会处理账号或密码中的特殊字符,避免代理URL被错误拆分。
  • timeout同时设置连接超时和读取超时,避免任务长期卡住。
  • raise_for_status把异常状态转换成显式错误,便于上层记录和重试。

不要把所有异常都立即重试。连接失败可以换一个已验证的代理后再试,目标站点返回频次提示时则应降低请求节奏,并检查任务是否符合站点允许的访问规则。

方法二:不安装第三方库,urllib怎么配置代理?

受限环境或轻量脚本可以使用Python标准库urllib,代价是会话复用和异步能力较弱。它适合部署依赖严格、请求量不大的内部工具,也适合用来排除第三方库配置因素。

完整代码如下:

import json
import os
from urllib.error import HTTPError, URLError
from urllib.parse import quote
from urllib.request import ProxyHandler, Request, build_opener


def build_proxy_url() -> str:
    host = os.environ["QG_PROXY_HOST"]
    port = os.environ["QG_PROXY_PORT"]
    user = os.getenv("QG_PROXY_USER")
    password = os.getenv("QG_PROXY_PASS")

    if user and password:
        auth = f"{quote(user, safe='')}:{quote(password, safe='')}@"
    else:
        auth = ""
    return f"http://{auth}{host}:{port}"


def main() -> None:
    proxy_url = build_proxy_url()
    opener = build_opener(
        ProxyHandler({"http": proxy_url, "https": proxy_url})
    )
    request = Request(
        "https://httpbin.org/ip",
        headers={"User-Agent": "QG-Proxy-Config-Demo/1.0"},
    )

    try:
        with opener.open(request, timeout=15) as response:
            body = response.read().decode("utf-8")
            print(json.loads(body))
    except HTTPError as exc:
        print(f"HTTP error: {exc.code}")
        raise
    except URLError as exc:
        print(f"Network error: {exc.reason}")
        raise


if __name__ == "__main__":
    main()

urllib没有额外安装成本,但工程能力要自己补齐。批量采集时至少增加日志、有限重试、代理失效时间缓存和任务级失败统计。若需求已经包含连接池、Cookie保持或复杂重试,不要为了少一个依赖而继续堆代码,切到requests.Session或采集框架更合适。

方法三:并发采集怎么用aiohttp配置代理?

并发任务应把代理配置放进异步请求入口,并用信号量控制真实并发,而不是一次创建大量协程。aiohttp适合网站可用性监测、公开页面批量检查这类I/O密集任务,但并发值必须根据目标站点规则和自身带宽逐步验证。

先安装依赖:

python -m pip install aiohttp

完整代码如下:

import asyncio
import os
from typing import Any

import aiohttp

TARGETS = [
    "https://httpbin.org/ip?task=1",
    "https://httpbin.org/ip?task=2",
    "https://httpbin.org/ip?task=3",
]


def load_proxy_config() -> tuple[str, aiohttp.BasicAuth | None]:
    host = os.environ["QG_PROXY_HOST"]
    port = os.environ["QG_PROXY_PORT"]
    user = os.getenv("QG_PROXY_USER")
    password = os.getenv("QG_PROXY_PASS")
    proxy_url = f"http://{host}:{port}"
    proxy_auth = aiohttp.BasicAuth(user, password) if user and password else None
    return proxy_url, proxy_auth


async def fetch(
    session: aiohttp.ClientSession,
    semaphore: asyncio.Semaphore,
    url: str,
    proxy_url: str,
    proxy_auth: aiohttp.BasicAuth | None,
) -> dict[str, Any]:
    async with semaphore:
        for attempt in range(1, 3):
            try:
                async with session.get(
                    url,
                    proxy=proxy_url,
                    proxy_auth=proxy_auth,
                ) as response:
                    response.raise_for_status()
                    return {"url": url, "data": await response.json()}
            except (aiohttp.ClientError, asyncio.TimeoutError) as exc:
                if attempt == 2:
                    return {"url": url, "error": str(exc)}
                await asyncio.sleep(attempt)
    return {"url": url, "error": "unexpected state"}


async def main() -> None:
    proxy_url, proxy_auth = load_proxy_config()
    timeout = aiohttp.ClientTimeout(total=20, connect=5)
    semaphore = asyncio.Semaphore(3)

    async with aiohttp.ClientSession(timeout=timeout) as session:
        tasks = [
            fetch(session, semaphore, url, proxy_url, proxy_auth)
            for url in TARGETS
        ]
        results = await asyncio.gather(*tasks)

    for result in results:
        print(result)


if __name__ == "__main__":
    asyncio.run(main())

异步配置最容易出现两个误判。第一,协程数量不等于合理并发,信号量才是并发闸门。第二,重试不能无限叠加,代码里只做有限次数重试,并在最终失败时保留URL和错误原因。这样才能区分代理连接问题、目标响应问题和程序解析问题。

如果代理IP存活较短,应按截止时间分批调度任务。不要让同一批任务跨越代理有效期,也不要每发一个请求就调用一次提取接口。青果国内短效代理的按量提取规格中,IP存活周期为1分钟,单次提取上限为200,单IP带宽为2Mbps(来源:青果网络官网)。这类参数更适合按批次装载代理,再把同批任务限制在可用窗口内。

方法四:Scrapy项目怎么统一注入代理?

Scrapy应通过下载中间件集中写入代理配置,避免每个Spider重复处理鉴权和切换。这种方式适合网站采集器等长期工程,后续可以在中间件里加入代理池、失败计数和刷新逻辑。

先安装依赖:

python -m pip install scrapy

下面是一份可直接通过runspider运行的单文件示例:

import base64
import os

import scrapy
from scrapy import Request
from scrapy.crawler import CrawlerProcess


class ProxyMiddleware:
    def __init__(self) -> None:
        host = os.environ["QG_PROXY_HOST"]
        port = os.environ["QG_PROXY_PORT"]
        self.proxy_url = f"http://{host}:{port}"

        user = os.getenv("QG_PROXY_USER")
        password = os.getenv("QG_PROXY_PASS")
        if user and password:
            token = base64.b64encode(
                f"{user}:{password}".encode("utf-8")
            ).decode("ascii")
            self.proxy_auth = f"Basic {token}"
        else:
            self.proxy_auth = None

    def process_request(self, request: Request, spider: scrapy.Spider) -> None:
        request.meta["proxy"] = self.proxy_url
        if self.proxy_auth:
            request.headers["Proxy-Authorization"] = self.proxy_auth


class ProxyCheckSpider(scrapy.Spider):
    name = "proxy_check"
    start_urls = ["https://httpbin.org/ip"]

    custom_settings = {
        "DOWNLOADER_MIDDLEWARES": {
            "__main__.ProxyMiddleware": 350,
        },
        "CONCURRENT_REQUESTS": 4,
        "DOWNLOAD_TIMEOUT": 15,
        "RETRY_TIMES": 1,
        "LOG_LEVEL": "INFO",
    }

    def parse(self, response: scrapy.http.Response):
        yield {
            "status": response.status,
            "body": response.json(),
        }


if __name__ == "__main__":
    process = CrawlerProcess()
    process.crawl(ProxyCheckSpider)
    process.start()

保存为proxy_spider.py后执行:

scrapy runspider proxy_spider.py -O proxy_result.json

正式项目里,中间件还应维护代理状态。建议把代理记录设计成server、deadline、fail_count、last_error4个字段。请求前检查截止时间,请求后按错误类型累计失败,不要因为一次业务响应异常就立刻淘汰代理。若不同采集任务对地区、会话和频次的要求不同,应分开管理代理队列,避免一个任务的调用节奏影响其他任务。

4种方法应该怎么选?

选择标准不是代码长短,而是任务生命周期和并发模型。单次脚本优先简单,长期任务优先集中治理,只有确定需要并发时才引入异步。

方法 适合场景 主要优点 需要补齐的能力
requests 单次验证、低频接口采集 语义直接,排查成本低 会话复用、代理刷新、统计
urllib 受限部署、轻量内部脚本 无第三方依赖 连接复用、重试、日志
aiohttp 批量检查、异步I/O任务 并发控制集中 限流、批次切换、失败归因
Scrapy 长期网站采集器 中间件统一治理 代理池状态、任务隔离、监控

无论选择哪一种,都建议按同一顺序自测:

  1. 用出口查询接口确认请求确实经过代理。
  2. 连续请求并记录状态、耗时和出口IP。
  3. 等待一个代理周期后,验证刷新逻辑是否生效。
  4. 在允许的访问规则内逐步增加并发,观察错误类型而不是只看错误总数。
  5. 日志隐藏账号、密码和完整提取链接,只保留request_id等定位字段。

代理IP只解决请求出口与环境隔离问题,不替代数据授权、采集节奏设计和隐私保护。采集公开数据也应执行最小化原则,只保存业务必要字段,并为失败重试设置明确上限。

Python数据抓取配置代理,应该落到青果哪类产品?

回到本篇判断:代码框架决定代理怎么接入,任务周期决定代理产品怎么选。高频公开数据采集需要业务自己控制IP批次时,可对应青果网络的国内短效代理。按量提取1万个IP为27元,有效期45天,IP存活1分钟,单次提取上限200(来源:青果网络官网)。长期运行的网站采集器若不想在代码内维护切换逻辑,可对应国内隧道代理。请求数5规格一个月360元,每次请求换IP,带宽峰值5Mbps(来源:青果网络官网)。前者把调度权留在代码,后者把切换交给服务端。选型不是看哪段代码更短,而是看团队愿意在哪一层承担状态管理。

常见问题

Q1:访问HTTPS地址时,为什么代理URL仍写http://?

A:这里的http://描述的是客户端连接代理服务器所用的协议,不是目标网页协议。访问HTTPS目标时,HTTP代理通常通过CONNECT建立通道。实际配置必须以服务商给出的协议为准,不能把目标URL的https://直接复制给代理地址。

Q2:白名单验证和账密验证应该怎么选?

A:固定云服务器、出口公网IP稳定时,白名单配置更省去代码内的凭据处理。开发机、弹性环境或公网IP经常变化时,账密验证更容易迁移。无论选哪种,都不应把密钥写进代码仓库,优先使用环境变量或密钥管理服务。

Q3:短效代理需要每个请求都重新提取吗?

A:通常不需要。更合理的做法是读取代理的截止时间,按可用窗口建立任务批次,并在到期前刷新。每个请求都调用提取接口会增加接口压力,也会让任务状态难以追踪。只有产品明确按请求自动切换时,才把切换交给服务端。

Q4:代理请求失败后应该立即更换IP吗?

A:先区分错误来源。连接超时、代理鉴权失败和目标站点的业务状态不是同一类问题。连接类错误可以在有限次数内更换已验证代理,鉴权错误应检查白名单或账密,频次提示则应降低请求节奏。不要用无限重试掩盖配置错误。

Q5:并发值应该设多大?

A:没有脱离业务的固定答案。应从较低并发开始,记录成功率、连接耗时、目标响应和代理出口分布,再逐步调整。我们青果网络在网站采集器实践中更看重并发下的错误归因:只有把代理、目标站点和解析程序分开统计,调参才有依据。

Q6:这4段代码可以直接用于生产吗?

A:它们包含代理配置、鉴权、超时和基础异常处理,可作为接入基线。生产环境还要补充结构化日志、指标监控、凭据轮换、代理状态缓存、任务去重和合规审计。先在获授权的数据源上小规模验证,再按实际错误分布完善工程能力。

推荐阅读
手把手教你配置 SOCKS5 代理,新手小白也能上手!

当谈到代理技术时,SOCKS5代理凭借其高兼容性、快速的传输性能和广泛的适用场景,成为了许多用户与开发者的首选。不管你是想提升爬虫数据采集的成功率,还是优化跨区域网络连接,都需要配置SOCKS5代理。今天,我们将带你从零开始学习SOCKS5代理的配置方法。不论你是小白用户第一次接触代理,还是需要优化...

2025-01-23
SOCKS5代理IP
代理http的是什么,有什么用

在数据驱动的世界里,无论是企业还是个人开发者,都离不开数据采集。采集数据信息不仅帮助我们了解市场动态,更支撑了大数据分析、机器学习等前沿技术的发展。然而,随着数据量的不断增大以及网络环境的复杂性,如何保证数据采集的效率和稳定性已经成为了一项不可忽视的挑战。而代理HTTP在当中扮演了重要的角色。 ...

2024-08-02
HTTP代理
国外代理ip节点哪里购买?高质量海外代理购买方法

您是否需要一篇深入且实用的指南来解答“国外代理IP节点哪里购买”的问题?网络时代,各类用户对国外代理IP的需求逐渐增加,无论是开发者、数据职业者,还是企业级用户,选择高质量的海外代理IP至关重要。那么,如何才能购买到适合自身需求的高质量代理IP呢?这篇文章将从购买渠道、选择要点和使用方法等方面为您详...

2025-07-24
国外代理IP
3分钟了解:静态IP和动态IP的区别具体在哪里?

如果你是一名开发者、网络管理员,或者是对网络技术感兴趣的小伙伴,想必你时常会听到“静态IP”和“动态IP”这两个名词。它们在互联网世界里扮演着重要角色,却存在显著差异。在日常工作的不同场景中,如何正确选择两者,才能更高效地解决实际问题? 本文将带你在3分钟内轻松搞懂静态IP和动态IP的主要区别...

2025-01-16
动态代理IP 静态代理IP
IP 隧道深度解析:原理、优势与实战选型

很多团队第一次接触“IP 隧道”(也常被称作“隧道代理”)时,会把它与传统网络中的 GRE、IPsec 等隧道概念混为一谈。二者确有渊源,却服务于不同目标:网络隧道更偏向专网互联与封装转发;而代理领域的 IP 隧道,则是通过一个稳定的入口节点,把后端海量出口 IP 的调度、轮换与质量控制“藏在门后”...

2025-09-30
http隧道代理 隧道代理IP
深入解析动态ip:什么是动态IP?动态IP与静态IP对比

在日常生活和企业应用中,IP地址是每台设备接入互联网的“身份标识”。大多数人每天使用的其实并不是固定不变的地址,而是运营商临时分配的 动态IP。与静态IP相比,动态IP更普遍、更经济,也更适合普通用户和一些大规模任务。本文将深入解析动态IP的特征及应用场景。 1 什么是动态IP 动态I...

2025-09-23
静态代理IP 动态代理IP
扫码添加专属客服
扫码关注公众号