news 2026/7/29 12:23:07

异步爬虫aiohttp使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
异步爬虫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之间左右,有些网站会有限流、频繁请求检测等,这种情况下并发的请求大部分都拿不到数据,需要降低并发量、增加失败重试等机制。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/29 12:19:23

知识干货 | 机器人开发最大的时间黑洞,其实不是算法

0. 前言机器人平台的发展,本质上不是让机器人拥有更多功能,而是让开发者拥有更多时间。如果你做过移动机器人开发,应该会发现,现在选择一个机器人平台,已经不仅仅是在选一块底盘。除了运动性能,开发效率、系…

作者头像 李华
网站建设 2026/7/29 12:19:14

Python实现目录扫描与import语句提取工具

1. 项目概述:Python实现目录扫描与import语句提取 在日常Python项目维护或代码审计中,经常需要快速分析项目依赖关系。手动检查每个文件的import语句既低效又容易遗漏。这个Python脚本正是为解决这个问题而生——它能递归扫描指定目录下的所有.py文件&am…

作者头像 李华
网站建设 2026/7/29 12:18:59

研发流水线工具选型指南:五大核心维度与主流方案对比

1. 研发提效工具的核心价值与选型困境 在软件研发领域,效率提升一直是团队持续追求的目标。过去五年间,我参与过从初创公司到万人规模企业的数十个研发效能改进项目,一个不变的规律是:当团队规模超过20人时,手工管理代…

作者头像 李华
网站建设 2026/7/29 12:17:25

物联网安全连接方案:PIC18F57K42与A5000加密模块实战

1. 物联网安全连接的核心挑战在工业物联网项目中,我最近用PIC18F57K42微控制器和A5000加密模块构建了一套安全连接方案。公共WiFi环境就像透明的玻璃房,所有数据都在裸奔;而私有云虽然看似安全,但内部威胁同样不容忽视。A5000硬件…

作者头像 李华
网站建设 2026/7/29 12:16:27

智创共赢|暴雨装备解码产业实践‌

近日,在“强基固链质领未来—服务器供应链成熟度评估与生态共建分论坛”上,暴雨亮相论坛。作为2026年服务器产业供需对接活动的核心环节,本次分论坛由中国计算机行业协会信息技术产品供应链成熟度专业委员会主办,旨在通过标准宣贯…

作者头像 李华