我试图在Python中制作Reddit Bot,但我遇到了一个问题。 机器人的目标是阅读Reddit搜索" get_tweets"的评论。当它发现这一点时,它将读取与此类似的整个注释:
get_tweets("TWITTER_USERNAME",NUMBER_OF_TWEETS,"INCLUDE_RE_TWEETS","INCLUDE_REPLIES")
评论将作为一项功能,4个参数将由用户评论确定。一个例子可以是:
get_tweets("BarackObama",5,"no","yes")
我认为我已经涵盖了所有内容,除了我不能将评论作为函数执行,因为当我尝试它时会出现此错误:
SyntaxError: unqualified exec is not allowed in function 'run_bot' it contains a nested function with free variables
以下是整个代码(twitter和reddit的身份验证除外):
keywords = ['get_tweets']
cache = []
tweets_list = []
def get_tweets(user,num,rt,rp):
tline = api.user_timeline(screen_name=user, count=num)
tweets = []
for t in tline:
reply = t.in_reply_to_screen_name
tweet = t.text
if rt.lower() == 'no' and rp.lower() == 'no':
if tweet[0:2] != 'RT' and reply == None:
tweets.append(tweet + ' | Date Tweeted: ' + str(t.created_at))
if rt.lower() == 'yes' and rp.lower() == 'no':
if tweet[0:2] == 'RT' and reply == None:
tweets.append(tweet + ' | Date Tweeted: ' + str(t.created_at))
if rt.lower() == 'no' and rp.lower() == 'yes':
if tweet[0:2] != 'RT' and reply != None:
tweets.append(tweet + ' | Date Tweeted: ' + str(t.created_at))
if rt.lower() == 'yes' and rp.lower() == 'yes':
if tweet[0:2] == 'RT' and reply != None:
tweets.append(tweet + ' | Date Tweeted: ' + str(t.created_at))
tweets_list = tweets
def run_bot():
subreddit = r.get_subreddit('test')
print('Searching...')
comments = subreddit.get_comments(limit=100)
for comment in comments:
comment_text = comment.body.lower()
isMatch = any(string in comment_text for string in keywords)
if comment.id not in cache and isMatch:
print('Found comment: ' + comment_text)
exec comment_text
cache.append(comment.id)
start = []
end = []
open_p = comment.index('(')
text = ''
for a in re.finditer(',', comment):
start.append(a.start())
end.append(a.end())
num = comment_text[end[0]:start[1]]
user = comment_text[open_p:start[0]]
for tweet in tweets_list:
text.append(' | ' + tweet + '\n\n')
if num == 1:
reply = 'Here is the latest tweet from ' + user + ':\n\n' + text + '\n\n***\nI am a bot.'
else:
reply = 'Here are the last ' + num + ' tweets from ' + user + ':\n\n' + text + '\n\n***\nI am a bot.'
comment.reply(reply)
run_bot()
答案 0 :(得分:3)
使用exec
或eval
是一个巨大的安全问题!您可以尝试的最好的方法是使用正则表达式从字符串中提取参数,或者使用,
简单地对其进行分解,然后使用该函数调用您的函数。幸运的是,你只需要字符串和数字,因此不需要进行危险的解析
一种可能的解决方案是:
import re
def get_tweets(user, num, rt, rp):
num = int(num)
print user, num, rt, rp
comment_text = 'get_tweets("BarackObama",5,"no","yes")'
# capture 5 comma separated parts between '(' and ')'
pattern = r'get_tweets\(([^,]*),([^,]*),([^,]*),([^,]*)\)'
param_parts = re.match(pattern,comment_text).groups()
# strip away surrounding ticks and spaces
user,num,rt,rp = map(lambda x:x.strip('\'" '), param_parts)
# parse the number
num = int(num)
# call get tweets
get_tweets(user,num,rt,rp)
打印:
BarackObama 5 no yes
缺点:
'
或"
开头/结尾时才有效,我猜可以假设(如果我错了,请纠正我)。< / LI>
优点:
,
完成的,因此您也可以完全删除使get_tweets(BarackObama,5,no,yes)
有效的刻度。rt
/ rp
的无效参数......这将导致异常或根本没有推文。 get_tweets
返回一个值,而不需要使用全局变量。答案 1 :(得分:1)
我想出来了!我使用eval()
代替exec
感谢@jwodder警告我一个非常糟糕的错误,我和其他帮助我修复代码的人。