为了账号安全,请及时绑定邮箱和手机立即绑定

如何确保我的 KeyboardInterrupt except 会做我需要的事情

如何确保我的 KeyboardInterrupt except 会做我需要的事情

qq_花开花谢_0 2021-11-09 20:45:11
我正在制作电子邮件爬虫,伪系统如下阶段1。1.从url获取所有链接阶段 2。2.抓取邮件第 3 阶段。3.抓取链接 第 4 阶段。4.如果所有链接都处理完毕,转到end_scene(它只是问我想在哪里保存它们等)4.1 如果发生中断,转到end_scene主要操作部分在 stage2 下,while len(unprocessed_urls) 我将使用我的逻辑来创建 url 和一个try except用于请求 url 响应的逻辑,这就是魔术发生的地方。 在这里,我可以简单地放置一个except KeyboardInterrupt并将其发送到我的函数。现在问题出现在我正在抓取电子邮件的第 3 阶段,这部分不在任何try/except块中,所以我无法真正实现中断器,或者我不知道如何在没有突然停止的情况下进行核心问题是在某个时刻,如果我按下ctrl+c它会抛出默认错误异常并且我的代码永远不会运行。这是逻辑:   # process urls one by one from unprocessed_url queue until queue is emptywhile len(unprocessed_urls):     ...URL processing...     try:               ...heres the request is made...        response = requests.get(url, timeout=3)        done = True    except requests.exceptions.ConnectionError as e:        print("\n[ERROR]Connection Error:")        print(e)        continue    except requests.Timeout as e:           print("\n[ERROR]Connection Timeout:")        print(e)        continue    except requests.HTTPError as e:           print("\n[ERROR]HTTP Error:")        print(e)        continue    except requests.RequestException as e:           print("\n[ERROR]General Error:")        print(e)        continue            ...this works...        # Check for CTRL+C interruption    except KeyboardInterrupt:            end_scene()    # extract all email addresses and add them into the resulting set      ...email extraction logic...    if len(new_emails) is 0:       ...print no emails...    else:       ...print emails found...            # create a beutiful soup for the html document    soup = BeautifulSoup(response.text, 'lxml')所以问题是,当启动任何键盘中断时,我如何构建我的代码以确保我可以运行我的代码?
查看完整描述

2 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

#!/usr/bin/env python

import signal

import sys

def signal_handler(sig, frame):

        print('You pressed Ctrl+C!')

        sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

print('Press Ctrl+C')

signal.pause()

从如何在 Python 中捕获 SIGINT?


我建议您使用并注册适当的信号处理程序,至少如果您的主要目标是简单地捕获任何用户/系统中断。


这是清理任何退出/中断的好方法。

如果您将应用程序作为服务运行以处理关闭事件等,也可以使用。


查看完整回答
反对 回复 2021-11-09
?
largeQ

TA贡献2039条经验 获得超7个赞

我觉得这可能不是正确的方法,但您可以尝试使用contextmanager:


import time

from contextlib import contextmanager


# build your keyboard interrupt listener

@contextmanager

def kb_listener(func):

    print('Hey want to listen to KeyboardInterrupt?')

    try:

        yield func

    except KeyboardInterrupt:

        print("Who's there?")

        interrupt()      # <--- what you actually want to do when KeyboardInterrupt


    # This might not be necessary for your code

    finally:             

        print('Keyboa^C')


# sample KeyboardInterrupt event

def interrupt():         

    print("KeyboardInterrupt.")


# sample layered function

def do_thing():          

    while True:

        print('Knock Knock')

        time.sleep(1)


with kb_listener(do_thing) as f:

    f()

测试输出:


Hey want to listen to KeyboardInterrupt?

Knock Knock

Knock Knock

Knock Knock

Who's there?

KeyboardInterrupt.

Keyboa^C

至少这样您就不需要将整个函数包装在一个try... except块中。


查看完整回答
反对 回复 2021-11-09
  • 2 回答
  • 0 关注
  • 278 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信