F.W。这不仅仅是一个PRAW问题,它比PRAW更倾向于Python。欢迎Python人士贡献力量,请注意,这不是我的母语xD!
基本上,我正在使用执行以下操作的PRAW编写Reddit机器人:
- 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循环花费的时间太长。不过我可能错了!
这个问题(如您所说)有点零星,但我已经缩小了范围。事实证明,尝试获取由/ u / AutoModerator主持的子redredit有时会超时(大概是因为列表很长)。
这是我发现问题的方式。如果您仅对解决方案感兴趣,请跳过此部分。
首先,我修改了脚本以使用try
和except
捕获异常发生时的情况。您的回溯告诉我,这是在以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
,这是检查条件是否为假的常规方法。