V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
qazwsxkevin
V2EX  ›  Python

请教 try 抛出异常后,有没有轻松回收(这个线程)内存的实现方法?

  •  
  •   qazwsxkevin · 2019-10-26 12:26:30 +08:00 · 3043 次点击
    这是一个创建于 1856 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在的做法是各位大佬认为鄙夷的方式,
    抱歉,我还在用 request-html,因为是一些原因,我现在只能(会 or 选择)用这个。。。 :-(

    while xxx:
     try:
                    pageStr = someFunc.GetReauestRenderHtmlSourcetoStr(linkURL)
                    if len(pageStr) > 150:
                        success = True
                        #xxx 省略
                        pass
                    else:
                       #是的,就是这样粗暴地抛出,而没有在 request-html 本身上去做对策
                        raise Exception()
                except:
                    # 记录下异常的时间节点
                    todoSomething(xxx)
    

    这有个不好,request-html 使用的是 pyppeteer+chrome,在 raise Exception()抛出后,chrome.exe 还会在进程里残留的,不会自己退出,以前单线程还好,在循环的开始加个 os.system("taskkill -f -im chrome.exe")就完事了,现在多进程就不能这么做了。。。请教各位大佬有什么好办法?学习学习...

    其实请教问题的实质,并不只是,想要把 request-html 如何回收得干净,如果 try 段里面,有更杂乱的调用话,try 本身是否有其它方法而不用根据 Exception 的内容,直接清干净? 还是只能老老实实,逐个应对?

    8 条回复    2019-10-26 16:23:29 +08:00
    Trim21
        1
    Trim21  
       2019-10-26 12:41:15 +08:00 via iPhone
    你说的是 try toexcept finally 的 finally 么
    qazwsxkevin
        2
    qazwsxkevin  
    OP
       2019-10-26 12:46:09 +08:00
    @Trim21 嗯嗯,是的,是 finnally 里,其实我原本的代码里,finally 是没有的...
    momocraft
        3
    momocraft  
       2019-10-26 12:52:48 +08:00   ❤️ 1
    資源管理 (保證釋放) 的常見寫法是釋放在 finally, 或者做成 with-resource
    ClericPy
        4
    ClericPy  
       2019-10-26 13:50:00 +08:00   ❤️ 2
    说的都真麻烦, 以前我也写过操作 Chrome 的库, 用的方式无外乎三个
    1. 用 with 包起来, exit 的时候清理进程
    2. 使用 weakref, 弱引用可以用 set 也可以用 dict, 自己选择, 维护一个 instance pool, 然后每隔一段时间扫一下不存在的, 做清理.
    3. 注册到 atexit 里面去

    你这是 Windows 上操作啊... 杀进程跨平台最好用还是 psutil, 不过看你只会用 Requests-html... 就不聊 cdp 方面的东西了
    ClericPy
        5
    ClericPy  
       2019-10-26 13:52:17 +08:00
    不过最简单的除了 atexit 和 with 外, 还是把任务写成 class, 在 __del__ 里面做处理, 这样每次回收内存就会杀死对应进程, 与你标题的要求比较贴近
    wysnylc
        6
    wysnylc  
       2019-10-26 15:20:16 +08:00
    题外话一下,java 没有这个烦恼
    qazwsxkevin
        7
    qazwsxkevin  
    OP
       2019-10-26 16:13:00 +08:00
    @momocraft
    @ClericPy
    嗯,明白了,感谢,回头我尽量把方式改为 with,有个基础概念不是很清晰的地方,with 包起来的内容,完成后我记得应该是全自动清的,而不用手动去 close,不知道有无理解错(刚起步写 python 没多久,以前基本没用过 with )


    另请教 @ClericPy:见过大佬您多次推荐 cdp,其实很早想请教在 github 或者其它地方,有无简单入门的 demo 例子,可以实现 cdp 去 open link,对页面 id/xpath 进行点击,获取页面 html 代码这些简单的起步学习? 官网的每个方法的解释,比较碎...
    ClericPy
        8
    ClericPy  
       2019-10-26 16:23:29 +08:00
    @qazwsxkevin with 上下文用法其实就是对一个包含 __enter__ 和 __exit__ 魔术方法的对象的一种语法糖, 也就是不管是否报错, 都会在代码块结束时候执行 exit 那部分. 找个靠谱点的教程吧, 或者单独搜搜 python with 的用法

    cdp 全称好像是 chrome devtools protocol, 是一套与 chrome debug remote 启动模式的交流协议, 包含 http 和 WebSocket 两部分, 而 chrome devtools 说白了, 可以简单理解成 chrome 浏览器按 F12 后底部出现的那个 devtools, 也就是和它交互用到的协议

    稍微理解的话, 可以点我头像的 github 里面有个 ichrome 项目, 通过 pip 可以安装上, 如果对协程不了解, 可以先用同步的那个版本, 看 example 的代码就知道了, open link 好像用的是 set_url 函数, 点击用的是 click 函数, 不过只支持 css 选择器
    鉴于 cdp 的 DOM 操作很多坑 (那个 pyppeteer 作者也这么说的), 所以还是使用注入 js 的方式来操作浏览器比较省事.
    同步和异步的 ichrome 调用方式里, chrome daemon 那个类使用 with 的方式是可以自动关闭进程的, 多个实例就是多个端口(需要区分端口)的进程

    说多了也没用, 直接体验吧, 前两天刚开了博客, 还没开始写操作 chrome 的博文, 估计得等一两周才会写...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1029 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 18:47 · PVG 02:47 · LAX 10:47 · JFK 13:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.