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

requests_html报Cannot allocate memory内存分配错误解决方案

问题根因

内存泄漏出在底层浏览器资源没释放,和你Python层关不关普通变量没关系,核心是三个问题:

  • r.html.render()开了keep_page=True,这个参数会让底层Pyppeteer调起的Chromium浏览器保留渲染页面对象,不会自动销毁。你每次循环跑一次请求,就多一个占内存的僵尸页面留在Chromium进程里,攒一天直接把0.5G内存吃满。你写的r.close()只能关Python层的响应对象,碰不到这些被标记为keep的浏览器页面资源。
  • 全局只建了一个HTMLSession无限循环复用,requests-html本身不会自动回收长期运行产生的浏览器内存碎片、残留进程,跑的时间越久内存占得越多。
  • 用了裸except吞所有异常,只要请求、渲染过程中抛错,代码直接return None,根本走不到r.close()的逻辑,异常场景下的资源直接漏了。
修复方案
  • 删掉keep_page=True,除非你真的需要跨请求复用同一个渲染页面,不然这个参数保持默认False就行,渲染完自动销毁对应的Chromium页面。
  • 别死攥着一个全局Session不放,每跑固定次数(比如10次请求)就主动把旧Session关了建个新的,把残留的Chromium进程彻底杀掉,清掉内存碎片。
  • 把资源释放的逻辑挪到finally块里,不管请求成不成功、报不报错,都确保响应对象能被关掉,别漏了异常分支的资源。
  • 给Chromium加低内存启动参数,适配你这台0.5G内存的小机器,压一压浏览器本身的内存开销。
修复后参考代码
import time
from requests_html import HTMLSession
from bs4 import BeautifulSoup as BS

# Chromium低内存启动参数
browser_args = [
    '--no-sandbox',
    '--disable-dev-shm-usage',
    '--disable-extensions',
    '--disable-gpu',
    '--disable-default-apps',
    '--no-zygote'
]

headers = {'accept': '*/*', 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'}
url = "my_url"

def get_site(session, site, params):
    r = None
    try:
        r = session.get(site, headers=headers, verify=False)
        script = """
                () =>{
                     $('.WEB_APPOINT_FORWARDBUTTON').click();
                }
                """
        # 移除keep_page=True,传入低内存参数
        r.html.render(script=script, sleep=5, browser_args=browser_args)
        soup = BS(r.html.html, 'html.parser')
        info = soup.find("div", {"id": "location"}).find_all("td", {"class": "calendar"})
        return info
    except Exception:
        return None
    finally:
        # 所有场景下都确保释放响应资源
        if r:
            try:
                r.close()
            except:
                pass

if __name__ == "__main__":
    request_count = 0
    ses = HTMLSession(browser_args=browser_args)
    while True:
        params = "same info"
        rez = get_site(ses, url, params)
        request_count += 1
        # 每10次请求重建一次Session,彻底清理Chromium残留进程
        if request_count % 10 == 0:
            ses.close()
            ses = HTMLSession(browser_args=browser_args)
        time.sleep(30)

额外说明:0.5G内存的机器跑Chromium本身冗余空间很小,如果修复后还是有缓慢内存上涨的情况,可以把重建Session的频率调高,比如每3-5次请求就重建一次,也可以直接在系统层面加定时任务,每天低峰期自动重启一次脚本,彻底释放所有内存。

内容的提问来源于stack exchange,提问作者The person with the question

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:12:24