Python-仅在两个关键字列表中都检测到关键字时才可能发送消息吗?

时间:2018-11-24 01:40:23

标签: python python-3.x python-requests slack-api praw

我有一个python脚本,可以从关键字列表keywords = ['camera', 'nikon']中检测到关键字,然后像以下所示向Slack发送一条消息

检测到关键字相机

“ Reddit发布网址”

“包含关键字的reddit评论”

如果脚本从第二个关键字列表color_keywords = ['red', 'blue']中检测到关键字,则它将发布以下内容

检测到关键字相机

“ Reddit发布网址”

“包含关键字的reddit评论”

检测到颜色

我的问题是,我是否能够以某种方式拥有脚本,因此如果找到了每个关键字列表中的关键字,它只会发送一条消息? 因此,如果仅从第一个列表中找到一个关键字,它将被忽略;如果从第二个列表中找到一个关键字,也将被忽略。但是如果它从两个列表中都找到了关键字,它将把消息发送到松弛状态。

下面是我当前的代码

MSG_TEMPLATE = """Keyword *{keyword}* detected
https://www.reddit.com{permalink}
```{comment_body}```"""

keywords = ['camera', 'nikon', 'canon']  
color_keywords = ['blue', 'red']

with open(save_path, 'r') as fp:
    alerted_comments = json.load(fp)

    for comment in comment_stream:
        if comment.id in alerted_comments:
            continue

        if comment.author:  # if comment author hasn't deleted
            if comment.author.name in ignore_users:
                continue

        if any(kw.lower() in comment.body.lower() for kw in keywords):
            found_kws = [kw for kw in keywords if kw.lower() in comment.body.lower()]

            msg = MSG_TEMPLATE.format(
                keyword=found_kws[0],
                permalink=comment.permalink,
                comment_body=comment.body
            )

            if any(kw.lower() in comment.body.lower() for kw in color_keywords):
                msg += "\n<!here> *A color was detected*"

            slack_data = {'text': msg, 'mrkdwn': True,}

            response = requests.post('https://hooks.slack.com/services/TB7AH6U2G/xxxxxxx/0KOjl9251TZExxxxxxxx',
                                             data=json.dumps(slack_data), headers={'Content-Type': 'application/json'})

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

当然!为简洁起见,以下代码摘录:

def find_keywords(comment, word_list):
    """:returns: List of matching keywords present in the comment, or the empty list"""
    return [word for word in word_list if word.lower() in comment.body.lower()]

for comment in comment_stream:
    if not should_be_ignored(comment):
        found_kws = find_keywords(comment, keywords)
        found_colors = find_keywords(comment, color_keywords)

        if found_kws and found_colors:
            # At this point, we're guaranteed to have *both* one or more keywords *and* one or more colors
            send_message(comment, found_kws, found_colors)

这里的主要见解是:首先创建匹配项列表,然后然后检查它们,以确定是否要发送消息。在这种情况下,只有两个列表都不为空时,您才可以继续发送消息。

should_be_ignored()send_message()的实现当然是留给读者的练习。:))

编辑:原始代码的完整实现:​​

def send_message(comment, keywords, colors):
    assert keywords and colors, "At this point, we should *only* be calling this function if we have at least one keyword and one color"

    MSG_TEMPLATE = """Keyword *{keyword}* and color *{color}* detected
    https://www.reddit.com{permalink}
    ```{comment_body}```"""
    msg = MSG_TEMPLATE.format(
        keyword=keywords[0],
        color=colors[0],
        permalink=comment.permalink,
        comment_body=comment.body
    )
    slack_data = {'text': msg, 'mrkdwn': True,}
    response = requests.post('https://hooks.slack.com/services/TB7AH6U2G/xxxxxxx/0KOjl9251TZExxxxxxxx',
                             data=json.dumps(slack_data), headers={'Content-Type': 'application/json'})


def should_be_ignored(comment, alerted):
    return comment.id in alerted or (comment.author and comment.author.name in ignore_users)


def find_keywords(comment, word_list):
    """:returns: List of matching keywords present in the comment, or the empty list"""
    return [word for word in word_list if word.lower() in comment.body.lower()]


keywords = ['camera', 'nikon', 'canon']  
color_keywords = ['blue', 'red']

with open(save_path, 'r') as fp:
    alerted_comments = json.load(fp)

for comment in comment_stream:
    if not should_be_ignored(comment, alerted_comments):
        found_kws = find_keywords(comment, keywords)
        found_colors = find_keywords(comment, color_keywords)

        if found_kws and found_colors:
            # At this point, we're guaranteed to have *both* one or more keywords *and* one or more colors
            send_message(comment, found_kws, found_colors)

请注意,我所做的(除了在发送消息之前必须同时具有颜色和关键字的新要求之外)是将您的一些业务逻辑提取到{{ 1}}和should_be_ignored()函数,希望可以阐明代码主体的意图。这应该是您开始使用的示例的直接替代。