Aiohttp异步并发实战:高效爬取小说榜单数据
2026/6/28 19:04:45 网站建设 项目流程

1. 为什么选择Aiohttp来爬取小说榜单?

在Python爬虫领域,Requests库可能是最广为人知的HTTP客户端库。但当你需要同时抓取几十页小说排行榜数据时,传统的同步请求方式就显得力不从心了。我曾经用Requests抓取20页小说数据,足足等了近1分钟——直到尝试了Aiohttp,同样的任务3秒就能完成。

Aiohttp是基于Python原生异步库Asyncio的HTTP框架,它的核心优势在于非阻塞I/O。简单来说,当程序发出网络请求时,CPU不用干等着服务器响应,而是可以继续处理其他任务。想象你在快餐店点餐:同步请求就像排长队一个个点单,而异步并发则是同时开放十个点餐窗口。

实测对比数据很能说明问题:

  • 同步请求20页小说数据:平均耗时58秒
  • Aiohttp并发请求20页数据:平均耗时2.8秒
  • 资源占用方面,Aiohttp的内存消耗仅为同步方式的70%

2. 搭建异步爬虫开发环境

2.1 基础环境配置

我推荐使用Python 3.8+版本,这是经过多个生产环境验证最稳定的Asyncio运行版本。别小看版本选择,之前用Python 3.6就遇到过事件循环不稳定的坑。安装核心依赖其实很简单:

pip install aiohttp==3.8.4 bs4==4.12.0 pandas==2.0.3

这里特别指定版本号是为了避免依赖冲突。遇到过有人装最新版aiohttp导致SSL证书错误,回退到3.8.4就正常了。

验证安装是否成功可以这样操作:

import aiohttp print(aiohttp.__version__) # 应该输出3.8.4

2.2 开发工具建议

虽然Jupyter Notebook适合快速验证,但我强烈建议使用PyCharm专业版开发完整爬虫项目。它的异步调试功能简直救命——能清晰看到每个协程的执行状态。配置运行时记得勾选"Gevent compatible"选项,这样断点调试时才不会卡住事件循环。

3. 实战:爬取起点热销榜完整流程

3.1 页面结构分析技巧

先打开起点中文网的24小时热销榜页面(注意要登录状态访问,否则可能触发反爬)。关键发现:

  1. 分页参数在URL中直接体现:page1page100
  2. 小说数据直接渲染在HTML中,不需要处理API接口
  3. 每本小说的信息包裹在<div class="book-mid-info">标签内

用Chrome开发者工具检查时,重点看Network面板的Doc类型请求。有个容易忽略的细节:起点网会在Cookie中埋入登录态,但我们的示例不需要登录也能获取基础榜单信息。

3.2 核心代码实现

先看完整的异步处理框架:

import aiohttp import asyncio from bs4 import BeautifulSoup async def fetch_page(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: return await response.text() async def scrape_multiple_pages(pages): tasks = [] for page in range(1, pages+1): url = f"https://www.qidian.com/rank/hotsales/page{page}/" tasks.append(fetch_page(url)) return await asyncio.gather(*tasks)

这里有两个关键点:

  1. ClientSession必须放在async函数内创建,全局session会导致连接池异常
  2. asyncio.gather就像同时发射多支箭,比挨个等待效率高得多

3.3 数据解析与存储

用BeautifulSoup解析要注意,它的方法默认是阻塞式的。我推荐使用lxml作为解析器:

def parse_html(html): soup = BeautifulSoup(html, 'lxml') books = [] for item in soup.select('.book-mid-info'): books.append({ 'title': item.select_one('h2').get_text().strip(), 'author': item.select_one('.name').get_text(), 'intro': item.select_one('.intro').get_text(strip=True) }) return books

存储到CSV时有个坑:异步任务可能同时写入文件。我的解决方案是先用内存暂存数据,最后统一写入:

import csv def save_to_csv(data, filename): with open(filename, 'w', newline='', encoding='utf-8-sig') as f: writer = csv.DictWriter(f, fieldnames=['title', 'author', 'intro']) writer.writeheader() writer.writerows(data)

4. 高级优化技巧

4.1 并发量控制策略

无限制并发会把服务器搞垮。Aiohttp提供了信号量控制:

sem = asyncio.Semaphore(10) # 最大10个并发 async def limited_fetch(url): async with sem: return await fetch_page(url)

根据实测,对起点网设置5-10个并发比较合适。太低了浪费性能,太高了可能触发429错误。

4.2 自动重试机制

网络请求难免失败,给关键请求加上重试:

async def fetch_with_retry(url, retries=3): for i in range(retries): try: return await fetch_page(url) except aiohttp.ClientError as e: if i == retries - 1: raise await asyncio.sleep(2**i) # 指数退避

4.3 性能监控方案

想知道哪部分最耗时?可以添加简单监控:

async def timed_fetch(url): start = time.monotonic() try: result = await fetch_page(url) elapsed = time.monotonic() - start print(f"{url} fetched in {elapsed:.2f}s") return result except Exception as e: print(f"{url} failed after {time.monotonic()-start:.2f}s") raise

5. 常见问题解决方案

5.1 SSL证书错误处理

在某些Windows环境下可能出现SSL错误,这时需要调整客户端配置:

conn = aiohttp.TCPConnector(ssl=False) # 不推荐生产环境使用 async with aiohttp.ClientSession(connector=conn) as session: ...

更安全的做法是手动指定证书路径:

conn = aiohttp.TCPConnector(ssl_context=ssl.create_default_context())

5.2 代理设置技巧

如果需要通过代理访问:

async with session.get(url, proxy="http://proxy.example.com") as resp: ...

注意代理字符串要包含协议头(http://或https://)

5.3 超时设置建议

默认情况下请求可能无限挂起,必须设置合理超时:

timeout = aiohttp.ClientTimeout(total=30) # 30秒总超时 async with session.get(url, timeout=timeout) as resp: ...

6. 项目完整代码结构

最终项目的标准目录结构应该是这样的:

novel_spider/ ├── main.py # 主逻辑 ├── utils.py # 工具函数 ├── config.py # 配置项 └── requirements.txt

在main.py中实现运行入口:

async def main(): htmls = await scrape_multiple_pages(20) all_books = [] for html in htmls: all_books.extend(parse_html(html)) save_to_csv(all_books, 'qidian_top100.csv') if __name__ == '__main__': asyncio.run(main())

这种结构方便后续扩展成分布式爬虫。我曾经用这个基础框架改造出了能抓取全网小说数据的系统,日均处理超过100万页面。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询