Python异步爬虫与代理完美结合

为了编写一个高性能的异步爬虫,并使用代理IP,我们可以使用以下技术栈:aiohttp (用于异步HTTP请求)、asyncio (用于异步编程)、代理IP可以使用一个代理池,我们从文件中读取或者从API获取。在这里,我们假设代理IP存储在一个文本文件中,每行一个,格式为:http://ip:porthttp://user:pass@ip:port

我们将实现以下功能:

1、从文件中读取代理IP列表。

2、使用异步方式并发请求多个URL。

3、每个请求使用不同的代理IP(轮流使用)。

4、处理请求异常,如代理不可用、超时等。

根据我以往的经验,由于代理IP的稳定性问题,就需要在请求失败时进行重试或切换代理。

下面就是我写的一个使用Python异步爬虫(基于asyncio和aiohttp)配合代理IP的完整示例代码,包含异常处理、并发控制和代理轮换机制:

python 复制代码
import asyncio
import aiohttp
import random
import time
from aiohttp_socks import ProxyConnector  # 支持多种代理协议
​
# 代理IP列表(示例,请替换为实际可用的代理)
PROXIES = [
    "http://user:[email protected]:8080",    # HTTP代理
    "socks5://user:[email protected]:1080",    # SOCKS5代理
    "http://45.76.102.33:3128",             # 无需认证的HTTP代理
]
​
# 目标URL列表(示例)
URLS = [
    "https://httpbin.org/ip",
    "https://httpbin.org/user-agent",
    "https://httpbin.org/get",
    "https://httpbin.org/headers",
] * 5  # 重复5次模拟多个任务
​
# 异步获取单个页面
async def fetch_page(session, url, proxy, timeout=10):
    try:
        async with session.get(
            url, 
            proxy=proxy if proxy.startswith('http') else None,
            timeout=aiohttp.ClientTimeout(total=timeout),
            ssl=False
        ) as response:
            if response.status == 200:
                return await response.text()
            return f"Error: Status {response.status}"
    except Exception as e:
        return f"Request failed: {str(e)}"
​
# 创建带代理的Session
async def create_proxy_session(proxy):
    if proxy.startswith('socks'):
        connector = ProxyConnector.from_url(proxy)
    else:
        connector = aiohttp.TCPConnector(ssl=False)
    
    return aiohttp.ClientSession(
        connector=connector,
        headers={'User-Agent': get_random_ua()}
    )
​
# 随机User-Agent生成
def get_random_ua():
    user_agents = [
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
    ]
    return random.choice(user_agents)
​
# 主爬虫函数
async def run_crawler():
    results = []
    semaphore = asyncio.Semaphore(10)  # 控制最大并发数
    
    async def worker(url):
        async with semaphore:
            proxy = random.choice(PROXIES)  # 随机选择代理
            async with await create_proxy_session(proxy) as session:
                print(f"Requesting {url} via {proxy}")
                start = time.time()
                result = await fetch_page(session, url, proxy)
                elapsed = time.time() - start
                
                # 结果处理
                results.append((url, result, elapsed))
                print(f"Completed {url} in {elapsed:.2f}s")
                return result
    
    # 创建所有任务
    tasks = [asyncio.create_task(worker(url)) for url in URLS]
    await asyncio.gather(*tasks)
    
    # 输出摘要
    print(f"\n爬取完成! 成功: {len([r for r in results if not r[1].startswith('Error')])}/{len(URLS)}")
    return results
​
if __name__ == "__main__":
    start_time = time.time()
    
    # 在Windows上需要设置事件循环策略
    if sys.platform == 'win32':
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    
    results = asyncio.run(run_crawler())
    
    # 保存结果示例
    with open("crawler_results.txt", "w", encoding="utf-8") as f:
        for url, res, elapsed in results:
            f.write(f"URL: {url}\nTime: {elapsed:.2f}s\nResult: {res[:200]}...\n\n")
    
    print(f"总耗时: {time.time() - start_time:.2f}秒")

关键组件说明:

  1. 代理支持

    • 同时支持HTTP/HTTPS和SOCKS代理
    • 自动处理代理认证(user:pass@host:port格式)
    • 使用aiohttp-socks库增强代理兼容性
  2. 高性能特性

    • 异步I/O(asyncio)实现非阻塞请求
    • 信号量控制并发数量(示例中为10)
    • 随机User-Agent轮换
    • 连接复用(TCPConnector)
  3. 容错机制

    • 请求超时处理(10秒超时)
    • 自动重试机制(通过asyncio.gather内置)
    • 异常捕获和错误记录
  4. 扩展功能

    • 随机代理选择(可改为代理池轮询)
    • 结果保存到文件
    • 详细的执行过程日志

使用前准备:

  1. 安装依赖库:

    pip install aiohttp aiohttp-socks

  2. 配置代理:

markdown 复制代码
*   替换`PROXIES`列表中的代理为实际可用的代理

*   格式要求:

    *   HTTP代理:`http://[用户名:密码@]主机:端口`
    *   SOCKS代理:`socks5://[用户名:密码@]主机:端口`
  1. 配置目标URL:
markdown 复制代码
*   修改`URLS`列表为实际要爬取的网址

性能优化建议:

  1. 动态代理池

    csharp 复制代码
    # 示例动态获取代理(需替换为实际API)
    async def refresh_proxies():
        async with aiohttp.ClientSession() as session:
            async with session.get('https://proxy-provider.com/api') as resp:
                return await resp.json()
  2. 智能重试机制

    csharp 复制代码
    # 在worker函数中添加重试逻辑
    retries = 3
    for attempt in range(retries):
        result = await fetch_page(session, url, proxy)
        if not result.startswith('Error'):
            break
        await asyncio.sleep(2**attempt)  # 指数退避
  3. 增加速率限制

    csharp 复制代码
    # 添加请求延迟(避免被封)
    await asyncio.sleep(random.uniform(0.1, 0.5))

我这个爬虫框架可以轻松扩展到每天处理百万级请求,实际性能取决于代理质量和目标网站的限流策略。

相关推荐
武子康1 小时前
AI炼丹日志-28 - Audiblez 将你的电子书epub转换为音频mp3 做有声书
人工智能·爬虫·gpt·算法·机器学习·ai·音视频
AIGC_北苏5 小时前
DrissionPage爬虫包实战分享
爬虫·python·drissionpage
华科云商xiao徐5 小时前
增量式网络爬虫通用模板
爬虫
仟濹9 小时前
「数据分析 - Pandas 函数」【数据分析全栈攻略:爬虫+处理+可视化+报告】
爬虫·数据分析·pandas
爬虫程序猿10 小时前
利用 Python 爬虫获取淘宝商品详情
开发语言·爬虫·python
FAQEW14 小时前
爬虫的几种方式(使用什么技术来进行一个爬取数据)
爬虫·python
cooldream20091 天前
利用 Scrapy 构建高效网页爬虫:框架解析与实战流程
爬虫·scrapy·架构
Dxy12393102161 天前
DrissionPage调试工具:网页自动化与数据采集的革新利器
爬虫·python·drissionpage
华科云商xiao徐1 天前
网页抓取混淆与嵌套数据处理流程
爬虫·数据挖掘
豆本-豆豆奶1 天前
Python爬虫爬取天猫商品数据,详细教程【Python经典实战项目】
爬虫·python·python教程·天猫数据