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

我正在制作电子邮件爬虫,伪系统如下


阶段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 empty

while 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')


所以问题是,当启动任何键盘中断时,我如何构建我的代码以确保我可以运行我的代码?


qq_花开花谢_0
浏览 279回答 2
2回答

RISEBY

#!/usr/bin/env pythonimport signalimport sysdef 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?我建议您使用并注册适当的信号处理程序,至少如果您的主要目标是简单地捕获任何用户/系统中断。这是清理任何退出/中断的好方法。如果您将应用程序作为服务运行以处理关闭事件等,也可以使用。

largeQ

我觉得这可能不是正确的方法,但您可以尝试使用contextmanager:import timefrom contextlib import contextmanager# build your keyboard interrupt listener@contextmanagerdef kb_listener(func):&nbsp; &nbsp; print('Hey want to listen to KeyboardInterrupt?')&nbsp; &nbsp; try:&nbsp; &nbsp; &nbsp; &nbsp; yield func&nbsp; &nbsp; except KeyboardInterrupt:&nbsp; &nbsp; &nbsp; &nbsp; print("Who's there?")&nbsp; &nbsp; &nbsp; &nbsp; interrupt()&nbsp; &nbsp; &nbsp; # <--- what you actually want to do when KeyboardInterrupt&nbsp; &nbsp; # This might not be necessary for your code&nbsp; &nbsp; finally:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; print('Keyboa^C')# sample KeyboardInterrupt eventdef interrupt():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; print("KeyboardInterrupt.")# sample layered functiondef do_thing():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; while True:&nbsp; &nbsp; &nbsp; &nbsp; print('Knock Knock')&nbsp; &nbsp; &nbsp; &nbsp; time.sleep(1)with kb_listener(do_thing) as f:&nbsp; &nbsp; f()测试输出:Hey want to listen to KeyboardInterrupt?Knock KnockKnock KnockKnock KnockWho's there?KeyboardInterrupt.Keyboa^C至少这样您就不需要将整个函数包装在一个try... except块中。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python