读取大型网站数据时遭遇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
相关产品推荐
相关产品推荐

