当前位置: 首页 > news >正文

异步爬虫aiohttp使用

目录

一、背景

二、应用场景

三、备注


一、背景

最近有个爬虫需求,页面是一个下拉框一个查询按钮,但是下拉框里有大概七八百多个选项,需求是要尽可能快的爬下来所有选项的数据。问了下AI,给出了aiohttp来做异步并发请求,之前也是没有用过,所以本文记录一下aiohttp使用方法。

二、应用场景

因为我们这个属于一个爬虫项目,框架任务的调度使用的aps管理,任务通过数据库查询得到,之前都是同步任务运行,但这个aiohttp是异步的函数功能,所以是要在任务里额外创建一个异步时间循环来运行异步任务。

def task(task_id=None, station_id=None, collect_date=None, province_code=None): """ 被aps定时任务查询,根据映射执行的具体任务入口 """ # 创建独立的事件循环 loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: results = loop.run_until_complete(async_crawl_flow()) return results finally: loop.close() class Crawler: ...... _sem = asyncio.Semaphore(10) # 控制并发数 async def async_crawl_flow(self): """ 异步主流程: 1. 获取下拉列表(拿到所有节点ID) 2. 并发查询每个节点详情 """ timeout = ClientTimeout(total=30) # aitohttp接受的proxy跟request有区别,是一个字符串 proxy_str = self.proxy.get('http') or self.proxy.get('https') async with aiohttp.ClientSession( timeout=timeout, headers=self.headers, cookies=self.cookie, proxy=proxy_str ) as session: print("开始获取下拉列表...") node_list = await self._fetch_node_list(session) if not node_list: print("未获取到节点列表,流程终止") return [] print(f"获取到 {len(node_list)} 个节点ID") print("开始并发查询节点详情...") results = await self._fetch_all_details(session, node_list) print(f"查询完成,成功 {len(results)} 条") return results # ============================================ # 第一步:获取下拉列表 # ============================================ async def _fetch_node_list(self, session: aiohttp.ClientSession) -> list[dict]: """ 调用下拉列表接口,提取所有节点ID """ try: async with session.post( 'https://xxx.com', json={} ) as resp: data = await resp.json() node_list = data.get("data", []) return node_list except Exception as e: print(f"获取下拉列表失败: {e}") return [] # ============================================ # 第二步:并发查询详情 # ============================================ async def _fetch_all_details(self, session: aiohttp.ClientSession, node_list: list[dict]) -> dict: """ 查询所有节点的详情 """ results = [] async def fetch_one_detail(node_info: dict): """查询单个节点详情""" id= node_info.get('id') name= node_info.get('name') async with self._sem: try: async with session.post( 'https://xxx.com', json={ 'phyunitId': id, 'dataTime': self.collect_date, }, timeout=ClientTimeout(total=10), ) as resp: if resp.status == 200: detail_data = await resp.json() results[id] = detail_data print(f"节点 {name} 查询成功") else: print(f"节点 {name} 返回状态码: {resp.status}") except asyncio.TimeoutError: print(f"节点 {name} 超时") # 创建所有任务并发执行 tasks = [fetch_one_detail(nl) for nl in node_list] await asyncio.gather(*tasks, return_exceptions=True) return results

三、备注

异步并发会同时向目标服务器发送n个请求过去,注意控制好信号量,一般建议在10-30之间左右,有些网站会有限流、频繁请求检测等,这种情况下并发的请求大部分都拿不到数据,需要降低并发量、增加失败重试等机制。

http://www.jsqmd.com/news/1287097/

相关文章:

  • CC3120 BoosterPack硬件解析与物联网Wi-Fi开发实战指南
  • 如何在网页中创造逼真的3D水面效果:ThreeJS Water终极指南
  • 公众号迁移公证书怎么弄?公众号迁移公证书怎么线上办理?
  • 2026电子会计档案提速:版式文件自动生成降低实施成本
  • AMD锐龙处理器免费调试工具:SMUDebugTool快速上手指南
  • 从新手到大师:拆解雕刻核心原理与系统学习路径
  • 上海南京西路大牌钻石回收!2026品牌溢价拆解换新回血对比 - 全国二奢机构参考
  • 八大网盘直链解析工具完整指南:告别限速,轻松获取高速下载链接
  • DeepSeek LeetCode 3777. 使子字符串变交替的最少删除次数 Java实现
  • 智创共赢|暴雨装备解码产业实践‌
  • 3D打印智能灯光系统DIY:从Arduino编程到光影艺术
  • 图形化编程入门:用Mind+画图掌握编程核心概念
  • FanControl终极指南:3分钟打造静音高效的Windows风扇控制系统
  • 先把 Agent 做好,再谈 AGI
  • 2026年7月短视频广告投流服务商推荐,无锡市有实力的短视频广告投流口碑推荐 - 品牌推荐师
  • 无人机地面站起飞条件检测系统:基于状态机与规则引擎的PyQt5实现
  • OpenClaw框架:System Prompt优化与Context Compression技术详解
  • 终极植物大战僵尸PC版修改器:完整使用指南与创新玩法
  • 2026环境好的雷霆战机线下服务门店精选推荐
  • 物联网设备射频PCB布局与天线设计实战指南:基于TI CC3220MODx模块
  • 词云AI·系统大更新!二级代理、线路管控、通话性能全面升级|产品更新
  • 武汉中职/中专想读日语专业选什么学校好? - 升学择校早知道
  • 2026下半年天津滨海新区继承纠纷横向测评,深度调研三个月回应房产继承分割 - 资讯快报
  • 绝地求生罗技鼠标宏完整指南:如何配置压枪脚本快速提升射击精度
  • FAST-LIO中IMU误差模型与噪声参数调优
  • DeepSeek LeetCode 3777. 使子字符串变交替的最少删除次数 Python3实现
  • NS-USBloader:一站式解决Switch游戏安装难题的跨平台工具
  • 基于CC2538与Z-Stack的智能电表设计:从硬件选型到ZigBee协议栈集成
  • LTE Cat 1bis模块与ARM Cortex-M4F的物联网通信方案
  • OpenClaw模块化AI框架解析与应用实践