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

读取大型网站数据时遭遇MemoryError异常的解决方法咨询

如何读取大型网页内容时避免MemoryError异常?

我尝试读取一个大型网站的页面数据时触发了MemoryError异常,相关代码如下:

import requests
requests.urllib3.disable_warnings()
search_page = "http://www.yachtworld.co.uk/core/listing/cache/searchResults.jsp?ps=99999"
y = requests.get(search_page, timeout=999999, stream=True)
result = y.text

当我尝试读取存储页面输出的result变量时触发了MemoryError异常,请问有没有办法完整读取数据且避免该异常?


解决方案:利用流式传输分块处理数据

你已经开启了stream=True,这是个好开头!但直接用y.text还是会把整个响应内容一次性加载到内存里,这就是导致MemoryError的核心原因。下面是几种实用的解决方案:

  • 分块读取并写入本地文件(最直接的方案)
    如果你的需求是保存页面内容到本地,完全不需要把所有内容都塞进内存。可以逐块读取并写入文件,内存占用会非常低:

    import requests
    requests.urllib3.disable_warnings()
    
    search_page = "http://www.yachtworld.co.uk/core/listing/cache/searchResults.jsp?ps=99999"
    with requests.get(search_page, timeout=999999, stream=True) as r:
        r.raise_for_status()  # 先确保请求没有出错
        with open("large_yacht_page.html", "wb") as f:
            # 每次读取8KB的块,可根据需求调整chunk_size值
            for chunk in r.iter_content(chunk_size=8192):
                f.write(chunk)
    

    iter_content会逐块返回响应数据,默认块大小是128KB,8KB是比较保守的内存友好设置。

  • 逐行处理文本内容
    如果页面是文本格式(比如HTML、JSON),可以直接逐行读取处理,完全不用加载全部内容:

    import requests
    requests.urllib3.disable_warnings()
    
    search_page = "http://www.yachtworld.co.uk/core/listing/cache/searchResults.jsp?ps=99999"
    with requests.get(search_page, timeout=999999, stream=True) as r:
        r.raise_for_status()
        for line in r.iter_lines():
            if line:  # 跳过空行
                decoded_line = line.decode('utf-8')
                # 在这里对单行内容做处理,比如提取标签、解析数据
                print(decoded_line[:100])  # 示例:打印每行前100个字符
    

    iter_lines会自动按行分割响应内容,适合处理结构化的文本类页面。

  • 用生成器封装处理逻辑
    如果需要对整个内容做自定义处理但不想一次性加载,可以用生成器来封装分块读取逻辑,按需返回处理后的内容:

    import requests
    requests.urllib3.disable_warnings()
    
    def process_large_page(url):
        with requests.get(url, timeout=999999, stream=True) as r:
            r.raise_for_status()
            # decode_unicode=True直接返回文本块,无需手动解码
            for chunk in r.iter_content(chunk_size=8192, decode_unicode=True):
                # 在这里对每个文本块做自定义处理,比如提取关键词、过滤内容
                yield chunk
    
    search_page = "http://www.yachtworld.co.uk/core/listing/cache/searchResults.jsp?ps=99999"
    for processed_chunk in process_large_page(search_page):
        # 在这里使用处理后的块,比如拼接写入或进一步解析
        pass
    

    生成器会按需返回处理后的内容,内存中始终只保留当前处理的小块数据。

关键注意事项

  • 务必保持stream=True,这是流式处理的前提,requests才不会提前把整个响应加载到内存。
  • 用with语句管理请求和文件,能自动关闭资源,避免内存泄漏。
  • 如果需要解析HTML,建议结合BeautifulSoup的SoupStrainer功能,只解析你需要的标签部分,进一步降低内存占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:34:08