如果在for循环中,Python超时

问题描述 投票:2回答:1

F.W。这不仅仅是一个PRAW问题,它比PRAW更倾向于Python。欢迎Python人士贡献力量,请注意,这不是我的母语xD!

基本上,我正在使用执行以下操作的PRAW编写Reddit机器人:

  • 循环显示未保存的帖子
  • 浏览所述帖子的评论(定位子评论)
  • 如果注释包含“!completed”,由提交者编写,或者是主持人,而不是提交者的父注释:
  • 做其他事情,例如打印(“嘿”)不,我没有很好地解释。例子更好,所以这里xD:

用例:

- Post by @dudeOne
 - Comment by @dudeTwo
  - Comment with "!completed" by @dudeOne
- Post by @dudeOne
 - Comment by @dudeTwo
  - Comment with "!completed" by @moderatorOne

print(“ Hey”)和:

- Post by @dudeOne
 - Comment by @dudeOne
  - Comment with "!completed" by @dudeOne

...不执行任何操作,甚至可能删除+消息@dudeOne。

这是我的凌乱代码(xD):

import praw
import os
import re

sub = "RedditsQuests"

client_id = os.environ.get('client_id')
client_secret = os.environ.get('client_secret')
password = os.environ.get('pass')

reddit = praw.Reddit(client_id=client_id,
                     client_secret=client_secret,
                     password=password,
                     user_agent='r/RedditsQuests bot',
                     username='TheQuestMaster')

for submission in reddit.subreddit(sub).new(limit=None):
    submission.comments.replace_more(limit=None)
    if submission.saved is False:
        for comment in submission.comments.list():
            if ((("!completed" in comment.body)) and ((comment.is_submitter) or ('RedditsQuests' in comment.author.moderated())) and (comment.parent().author.name is not submission.author.name)):
              print("etc...")

有一个相当大的堆栈,所以我将其添加到this bin中供您参考。在我看来,PRAW正在超时,因为if-in-for循环花费的时间太长。不过我可能错了!

python python-3.x praw
1个回答
0
投票

这个问题(如您所说)有点零星,但我已经缩小了范围。事实证明,尝试获取由/ u / AutoModerator主持的子redredit有时会超时(大概是因为列表很长)。

解决问题

这是我发现问题的方式。如果您仅对解决方案感兴趣,请跳过此部分。

首先,我修改了脚本以使用tryexcept捕获异常发生时的情况。您的回溯告诉我,这是在以if ((("!completed" in comment.body))开头的行上发生的,特别是在获取用户审核的子reddit时。这是我修改过的脚本:

for submission in reddit.subreddit(sub).new(limit=None):
    submission.comments.replace_more(limit=None)
    if submission.saved is False:
        for comment in submission.comments.list():
            try:
                if (
                    (("!completed" in comment.body))
                    and (
                        (comment.is_submitter)
                        or ("RedditsQuests" in comment.author.moderated())
                    )
                    and (comment.parent().author.name is not submission.author.name)
                ):
                    print("etc...")
            except Exception:
                print(f'Author: {comment.author} ({type(comment.author)})')

和输出:

etc...
etc...
Author: AutoModerator (<class 'praw.models.reddit.redditor.Redditor'>)
etc...
etc...
etc...
Author: AutoModerator (<class 'praw.models.reddit.redditor.Redditor'>)
etc...
etc...
etc...
etc...
etc...
etc...
etc...
Author: AutoModerator (<class 'praw.models.reddit.redditor.Redditor'>)
etc...
Author: AutoModerator (<class 'praw.models.reddit.redditor.Redditor'>)
etc...
etc...

考虑到这一点,我编写了一个非常简单的三行脚本来重现该问题:

import praw

reddit = praw.Reddit(...)

print(reddit.redditor("AutoModerator").moderated())

有时,此脚本会成功,但有时在相同的套接字读取超时时会失败。可能发生超时是因为AutoModerator审核了这么多subreddit(至少10,000),并且Reddit API需要太长时间来处理请求。

解决问题

您的脚本试图确定所讨论的Redditor是否是subreddit的主持人。您可以通过检查subreddit是否在用户审核的subreddit列表中来进行此操作,但是可以将其切换为检查用户是否在subreddit主持人列表中。这不仅不会超时,而且还会保存很多网络请求,因为您只需提取一次主持人列表。

The PRAW documentation of Subreddit显示了如何获取subreddit主持人的列表。就您而言,我们可以做到

Subreddit

然后,我们不检查moderators = list(reddit.subreddit(sub).moderator()) ,而是检查

"RedditsQuests" in comment.author.moderated()

您的代码随即变为

comment.author in moderators

在我的简短测试中,该脚本运行速度提高了许多倍,因为我们只获得了一次主持人列表,而不是获取所有发表评论的用户主持的所有子公告。


作为无关的样式注记,应该执行import praw import os import re sub = "RedditsQuests" client_id = os.environ.get("client_id") client_secret = os.environ.get("client_secret") password = os.environ.get("pass") reddit = praw.Reddit( client_id=client_id, client_secret=client_secret, password=password, user_agent="r/RedditsQuests bot", username="TheQuestMaster", ) moderators = list(reddit.subreddit(sub).moderator()) for submission in reddit.subreddit(sub).new(limit=None): submission.comments.replace_more(limit=None) if submission.saved is False: for comment in submission.comments.list(): if ( (("!completed" in comment.body)) and ((comment.is_submitter) or (comment.author in moderators)) and (comment.parent().author.name is not submission.author.name) ): print("etc...") 而不是if submission.saved is False,这是检查条件是否为假的常规方法。

© www.soinside.com 2019 - 2024. All rights reserved.