Python爬虫效率问题如何优化?

行业领域
不限
人工智能 区块链 大数据 医疗健康 教育培训 文娱传媒 消费升级 金融 电子商务 企业服务 VR/AR 旅游户外 餐饮业 房产家居 汽车交通 体育健身 生活服务 食品饮料 物联网 硬件 游戏 生产制造 物流运输 农业 批发零售 先进制造 社交社区 工具软件 服装纺织 建筑 开采 环保 能源电力 政务及公共服务 科研及技术服务

下面是 时间 一年的循环

这样 365 天*35 行业。在 selenium 点击 如何提高效率? aiohttp ? 如果是多台机器是是不是 dokcer+spalsh ?
Python爬虫效率问题如何优化?


17 回复

如果考虑 selenium 或者 splash 的话就不要追求效率了


核心思路:并行化 + 连接复用 + 减少阻塞

直接上代码,用 aiohttp + asyncio 替代 requests,这是解决爬虫效率问题的标准方案:

import asyncio
import aiohttp
from datetime import datetime

async def fetch(session, url):
    """异步获取单个页面"""
    try:
        async with session.get(url, timeout=10) as response:
            return await response.text()
    except Exception as e:
        print(f"Error fetching {url}: {e}")
        return None

async def worker(session, queue, results):
    """工作协程:从队列获取URL并处理"""
    while True:
        url = await queue.get()
        html = await fetch(session, url)
        if html:
            # 这里添加你的解析逻辑
            results.append(len(html))
        queue.task_done()

async def main(urls, concurrent_workers=50):
    """主函数:管理异步任务"""
    queue = asyncio.Queue()
    results = []
    
    # 将所有URL放入队列
    for url in urls:
        await queue.put(url)
    
    # 创建连接池(重点!复用TCP连接)
    connector = aiohttp.TCPConnector(limit=100, force_close=False)
    async with aiohttp.ClientSession(connector=connector) as session:
        # 启动工作协程
        workers = [
            asyncio.create_task(worker(session, queue, results))
            for _ in range(concurrent_workers)
        ]
        
        # 等待队列清空
        await queue.join()
        
        # 取消所有worker
        for w in workers:
            w.cancel()
    
    return results

# 使用示例
if __name__ == "__main__":
    # 你的URL列表
    urls = [f"https://httpbin.org/get?page={i}" for i in range(100)]
    
    start = datetime.now()
    results = asyncio.run(main(urls, concurrent_workers=50))
    elapsed = datetime.now() - start
    
    print(f"爬取 {len(urls)} 个页面,耗时 {elapsed.total_seconds():.2f} 秒")
    print(f"平均每个页面 {elapsed.total_seconds()/len(urls):.3f} 秒")

关键优化点:

  1. 异步IOasyncio 在等待网络响应时不会阻塞,可以同时处理多个请求
  2. 连接池TCPConnector 复用TCP连接,避免重复三次握手
  3. 并发控制:通过 concurrent_workers 参数控制并发数,避免被封IP
  4. 队列管理:任务队列确保所有URL都被处理

如果同步代码不能改,用 ThreadPoolExecutor 凑合:

from concurrent.futures import ThreadPoolExecutor
import requests

def fetch_sync(url):
    return len(requests.get(url).text)

with ThreadPoolExecutor(max_workers=20) as executor:
    results = list(executor.map(fetch_sync, urls))

一句话总结:用异步IO替代同步请求是本质提升。

现在就是点击的,因为如果每天都点击 就是 365 天 再加上 35 个行业,数字很大,那么 chrome 吃不消的

建议分析一下请求…直接请求的方式做

35 个栏目又不多,开 35 个 chrome 就 ok

分析请求加密很麻烦的,企名片 短信登录什么的,很累

你的意思是可以用 aiohttp 做了!

你对 aio 有什么执念,我说的是多线程 /进程 selenium 直接干

你试过嘛

你都用 selenium 了就不要问效率的问题了。
你应该会 xpath 语法吧,要效率直接上 scrapy 之类,解析每个类别的 url,直接异步发送请求,要担心的不是效率问题了,而是别把人家 web 服务器给爆了。

一直用的 requests,昨天试了下 selenium,结果被淘宝的滑块拦下了,唉。
搭车问问,有啥老版本的 ff 可以绕过 robot 模式嘛,主力用 chrome 不想降。

我是说 再 selenium 基础上提高效率啊。36535 这个数字很庞大啊。还有就是 2 个 36535

滑块也可以 selenium 滑动的

那你的意思是标签分开点击啊

能自己撸代码模拟的,为啥非要去 selenium 呢

企名片 你去看看,纯接口难

能获取到请求就尽量获取请求,直接发请求效率最快

回到顶部