You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

API调用场景下使用生成器的优势存疑:示例代码解析

为什么这个爬虫示例里的生成器看起来没用?

你说得完全正确!在这个给定的代码示例中,生成器确实没发挥出它的核心价值——因为你已经一次性把整个API响应都加载到内存里了,这时候用生成器和直接遍历列表几乎没有区别。

先拆解下当前代码的问题

咱们一步步看:

  1. response = requests.get(...) 已经把整个API返回的内容下载到了内存里,response.content是完整的字节串。
  2. json.loads(response.content) 把整个JSON转换成了内存中的字典对象,api_results['results']是一个包含所有角色数据的完整列表,已经全存在内存里了。
  3. 后面的yield character['name']只是逐个吐出这个列表里的元素,本质上和直接写for character in api_results['results']: print(character['name'])没有任何内存上的优势——因为整个列表已经占着内存了。

那什么时候生成器在爬虫场景里才有用?

生成器的核心优势是按需生成、延迟加载,要让它发挥作用,得把它和「分批获取数据」或者「流式处理数据」结合起来。比如SWAPI本身是支持分页的(返回结果里有next字段指向后续页面),我们可以用生成器来逐页爬取,每次只加载一页的数据到内存:

import requests
import json

def crawl():
    current_url = 'https://swapi.co/api/people'
    while current_url:
        # 只获取当前页的数据
        response = requests.get(current_url)
        api_results = json.loads(response.content)
        
        # 逐个yield当前页的角色名,处理完一页再取下一页
        for character in api_results['results']:
            yield character['name']
        
        # 更新为下一页的URL,没有下一页就会变成None,循环终止
        current_url = api_results.get('next')

# 遍历生成器时,内存里始终只存当前页的数据
for character_name in crawl():
    print(character_name)

这个改进版的优势就很明显了:哪怕API有1000页数据,你的内存里也只会同时存在一页的角色数据,处理完一页后,这页的数据就可以被垃圾回收释放内存,再去加载下一页——这才是生成器节省内存的正确用法。

另外还有一种场景:如果API返回的是超大的流式JSON(比如分块传输的大文件),你可以用生成器配合流式JSON解析库(比如ijson),不用把整个JSON加载到内存,而是逐个解析并yield元素,这时候生成器的内存优势也会非常显著。

总结

原示例里的生成器确实是多余的,因为数据已经被一次性全加载到内存了。但只要把生成器和「分批获取数据」「流式处理」结合起来,它就能帮你在处理大量数据时,把内存占用控制在很低的水平——这才是生成器在爬虫这类场景中的真正价值。

内容的提问来源于stack exchange,提问作者CleverDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:10:27