首页 > 解决方案 > 长时间运行时出现 Tweepy 错误

问题描述

我写了一个 Twitter 机器人,它时不时地发布一张来自 reddit 的图片。我在树莓派 4 上托管这个脚本,我希望它 24/7 运行。但是,过了一会儿我得到下一个错误:

tweepy.error.TweepError:发送请求失败:HTTPSConnectionPool(host='api.twitter.com', port=443):最大重试次数超过 url:/1.1/statuses/update_with_medi.json?status=https%3A%2F %2Fredd.it%2kftmohf(由 NewConnectionError 引起('<urllib3.connection.VerifiedHTTPSConnection object at 0xb4771550>: 无法建立新连接:[Errno -3] 名称解析临时失败'))

我认为正在发生的事情是无论出于何种原因它都无法访问 Twitter。我正在寻找的是如何解决此问题,或者如果无法避免,我如何稍后重试以再次运行该程序。

提前致谢。

如果您需要,这是完整的代码:

import praw
import json
import urllib.request
import tweepy
import time
import datetime
import os
import fnmatch
from PIL import Image  
import urllib.parse
from glob import glob
import wget

# Place your Twitter API keys here
ACCESS_TOKEN = 'ACCESS_TOKEN '
ACCESS_TOKEN_SECRET = ACCESS_TOKEN_SECRET 
CONSUMER_KEY = 'CONSUMER_KEY' 
CONSUMER_SECRET = 'CONSUMER_SECRET'

#Reddit we want to pick images from
SUBREDDIT = 'learnpython'

#Directory to save the images
PATH = '/home/pi/Desktop/img/'

#TXT file to save the posts you have already posted
POSTED_CACHE = 'posted_posts.txt'

#Max size images can be because twitter has a limit
MAX_SIZE = 3070000

#Reddit shorter url
REDDIT_URL = 'https://redd.it/'

#Time to rest between tweets or we will get banned from twitter
TIME_TO_SLEEP = 1800 #set on 30 minutes but should not be less than 20

reddit = praw.Reddit(
                        user_agent='user agen',
                        client_id='client id',
                        client_secret='client secret')


#See in the sub what posts have pngs or jpgs so you can post the images on twitter
#and get everything ready to be tweeted
def tweet_creator():
    post_ids = []
    post_urls = []

    subreddit = reddit.subreddit(SUBREDDIT)
    
    for submission in subreddit.hot(limit = 55):
        if not already_tweeted(submission.id):
            if '.png' in submission.url or '.jpg' in submission.url:
                get_image(submission.id, submission.url)
                if not too_big(submission.id,submission.url):
                    post_ids.append(submission.id)
                    post_urls.append(submission.url)
    print('[bot] Se han recopilado:'+str(len(post_ids))+' imagenes')
    return post_ids, post_urls
        

#This is the important function that will post the tweets and loop itself 
#for 20 or 30 hours because of the delay we talk about before 
def tweeter(posts_ids, posts_urls):
    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
    api = tweepy.API(auth)

    for i in range(0, len(posts_ids)):
        api.update_with_media(filename = PATH + posts_ids[i] + posts_urls[i][-4:], status = REDDIT_URL+posts_ids[i] )
        print('[bot:'+str(datetime.datetime.now().hour)+':'+str(datetime.datetime.now().minute)+':'+str(datetime.datetime.now().second)+'] posting link on twitter: redd.it/' + posts_ids[i])
        log_tweet(posts_ids[i])
        time.sleep(TIME_TO_SLEEP)
    print('[bot] Se acabaron los tweets')

#Get the image
def get_image(ids, url):
    opener = urllib.request.build_opener()
    opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
    urllib.request.install_opener(opener)
    #some help in case I forget how this work https://stackoverflow.com/questions/34692009/download-image-from-url-using-python-urllib-but-receiving-http-error-403-forbid

    urllib.request.urlretrieve(url, PATH+ids+url[-4:])

#Check the image is not too big
def too_big(ids,urls):
    found = False

    if os.path.getsize(PATH+ids+urls[-4:]) > MAX_SIZE:
        print('[bot]la imagen:' + ids+urls[-4:]+' es muy grande')
        log_tweet(ids)
        os.remove(PATH+ids+urls[-4:])
        found = True
    return found

#Check if the image has been already tweeted
def already_tweeted(ids):
    found = False
    with open(POSTED_CACHE, 'r') as in_file:
        for line in in_file:
            if ids in line:
                found = True
                break
    return found

#In case it has not been tweeted jet write it's id in the TXT
def log_tweet(ids):
    with open(POSTED_CACHE, 'a') as out_file:
        out_file.write(str(ids) + '\n')

def main():

    posts_ids, posts_urls = tweet_creator()
    tweeter(posts_ids, posts_urls)

#Loop forever
while True:
    main()

标签: pythontwitterconnectiontweepy

解决方案


这个程序是在中国开发的,因为某些原因,中国被禁止访问 Twitter。所以我使用了一个名为 shadowsockets 的代理,它可以将模式设置为全局。

可能会帮助你


推荐阅读