如何发布超过 280 个字符的推文?因此,如果字符串 > 280,则打印前 280 个字符,然后在该线程中再次使用其余字符发送推文

Posted

技术标签:

【中文标题】如何发布超过 280 个字符的推文?因此,如果字符串 > 280,则打印前 280 个字符,然后在该线程中再次使用其余字符发送推文【英文标题】:How to possibly tweet more than 280 chars? So if string > 280, print first 280 chars, then tweet again in that thread with the rest of the chars 【发布时间】:2021-08-05 17:46:45 【问题描述】:

抱歉标题不稳,字数限制(讽刺)。我创建了一个机器人,当它被提及时,它会从列表中随机选择一个字符串来响应,这很正常。

问题是我列表中的大多数字符串都超过 280 个字符,twitter 字数限制。此外,用户 twitter 句柄、“@”和用户名后面的空格(字符串应该从哪里开始)也计入字数限制

这是我想出的代码,但我很难过......

import replies # Separate file where all replies are stored
def reply_to_tweets():
    print("Scanning for new mentions...")
    last_seen_id = retrieve_id(FILE)
    mentions = api.mentions_timeline(last_seen_id, tweet_mode="extended")
    myself = api.me()
    for tweet in reversed(mentions): 
        if myself.screen_name in tweet.full_text: # If my @ is in the full text
            if tweet.in_reply_to_status_id is not None:
                continue
            last_seen_id = tweet.id 
            store_id(last_seen_id,FILE) 
            random_choice = random.choice(replies.strings_more_than_280)  # Random string chosen
            def splitter(chosen_string):
                return [char for char in chosen_string] # This part may be obsolete but it gives 
                                                        # me peace of mind as I know it counts 
                                                        # emojis and spaces!

            username = '@' + tweet.user.screen_name 
# There is a space at the beginning of every string in my list, so this should 
# account for the character after the @ where the string should go
            length_of_user = len(username) # WORKS
            
            splitter_in_action = splitter(random_choice)
            length_of_string = len(splitter_in_action)
# This is where the space is counted, since there's a space in the beginning of 
# the string already, then it'll count towards the length of the string when we 
# calculate it using the splitter() function

            difference = length_of_string - length_of_user
            difference2 = difference - length_of_user
            if length_of_string + length_of_user > 280: 
                print(username + random_choice[:difference2]) # status update goes here
                
# Now those last few lines of code, I'm just guessing, I have no idea how to 
# calculate for the difference in my string minus the user's @ and then tweet up
# to 280 chars, then tweet the rest later. It's probably simple but I am perplexed!!!

错误是 ['code': 186, 'message': 'Tweet needs to be a bit shorter.']

编辑:删除了整个错误回调(不确定它到底叫什么),只添加了上面的主要错误

任何帮助都会很大,因为我已经被困在这里一段时间了。这并不是要向人们发送垃圾邮件和烦人,只是我希望机器人打印的消息太长,所以是的,我知道这是很多代码,但我真的希望有人能启发我!

【问题讨论】:

您使用difference = length_of_string - length_of_user 计算的差异对您没有多大帮助,因为其中不涉及 280 的字符限制。所以假设我的tweet长度是320,length_of_user是5,相差315。所以当你用random_choice[:difference]发tweet时,它变成random_choice[:315],仍然超过280的限制。 嗨@Ank!回复晚了非常抱歉。我确实在你发布的那天看过你的建议,但对我来说现在是考试季节,所以我不得不暂时搁置我的爱好。我在脑海中玩过这个想法,但我只是没有一个方程式可以解释推文中的角色。但我确实想出了一些东西!我可以将我创建的用于返回用户名全长(包括@)的代码发给您吗?也许你可以从那里进一步帮助我? 这个问题你解决了吗? @Lifeiscomplex 还没有。我想这只是我不理解这里的数学。我进一步编辑了代码以反映我的更改和想法。 @Ank 谢谢我真的很感激!我已经编辑了代码以显示我的新想法。我认为在这一点上,我只是不了解我想要完成的事情背后的数学原理。 【参考方案1】:

这是一项正在进行的工作,需要根据您的用例进行更多测试。我做了一些研究并确定拆分长推文的最佳方法是使用textwrap。该模块将允许您将推文干净地分成块。

我在测试中只尝试了一条推文和一个推特句柄,但我相信下面的代码应该适用于您的用例,或者为您提供一个坚实的起点,以便将此功能融入您的代码。

如果您对代码有任何疑问,请告诉我。

import math
import textwrap

# the tweet in this list is 1471 characters in length
tweets = [
    'Four score and seven years ago our fathers brought forth upon this continent, a new nation, conceived in Liberty, '
    'and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, '
    'testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a '
    'great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those '
    'who here gave their lives that that nation might live. It is altogether fitting and proper that we should '
    'do this. But, in a larger sense, we can not dedicate—we can not consecrate—we can not hallow—this ground. '
    'The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. '
    'The world will little note, nor long remember what we say here, but it can never forget what they did here. '
    'It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have '
    'thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us—that '
    'from these honored dead we take increased devotion to that cause for which they gave the last full measure of '
    'devotion—that we here highly resolve that these dead shall not have died in vain—that this nation, under God, '
    'shall have a new birth of freedom—and that government of the people, by the people, for the people, shall '
    'not perish from the earth. —Abraham Lincoln']


twitter_handle = ['@MariahCarey']

for handle in twitter_handle:
    handle_length = len(handle)
    for tweet in tweets:

        # obtain length of tweet, which is 1471 characters
        tweet_length = len(tweet)

        # check length
        if tweet_length <= 280:
            # do some here

        elif tweet_length >= 280:

            # divided tweet_length / 280
            # You might consider adjusting this down 
            # depending on how you want to format the 
            # tweet.
            tweet_length_limit = tweet_length / 280

            # determine the number of tweets 
            # math.ceil is used because we need to round up
            tweet_chunk_length = tweet_length / math.ceil(tweet_length_limit) + handle_length

            # chunk the tweet into individual pieces
            tweet_chunks = textwrap.wrap(tweet,  math.ceil(tweet_chunk_length), break_long_words=False)

            # iterate over the chunks 
            for x, chunk in zip(range(len(tweet_chunks)), tweet_chunks):
                if x == 0:
                    print(f'handle 1 of len(tweet_chunks) chunk')
                else:
                    print(f'handle x+1 of len(tweet_chunks) chunk')
                    

打印输出:

# length 275
@MariahCarey 1 of 6 Four score and seven years ago our fathers brought forth upon this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any

# length 268
@MariahCarey 2 of 6 nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is

# length 278
@MariahCarey 3 of 6 altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate—we can not consecrate—we can not hallow—this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or

# length 276
@MariahCarey 4 of 6 detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It

# length 278
@MariahCarey 5 of 6 is rather for us to be here dedicated to the great task remaining before us—that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion—that we here highly resolve that these dead shall not have

# length 211
@MariahCarey 6 of 6 died in vain—that this nation, under God, shall have a new birth of freedom—and that government of the people, by the people, for the people, shall not perish from the earth. —Abraham Lincoln

【讨论】:

它工作得很好我真的很感激你不知道。我也从你的代码中学到了很多东西,虽然有些东西如果我仍然需要一点点理解,我可以开始看到一般的想法,如果我进一步看,我会理解的。我已经修改了您的解决方案,并且推文已发布!现在唯一的问题是他们以单条推文的形式发布推文,而不是回复提到我的人。但我会弄清楚,这只是移动一些 if 语句的问题。再次感谢各位用户! @SergioBoySV 你的问题是一个有趣的问题。我很高兴我的代码对您有所帮助。快乐编码! @SergioBoySV 你最终有没有想过如何将它们作为回复而不是单个推文推送? @epkalibbala 自从我从事这个项目以来已经有一段时间了,但根据我最后的记忆,我确实找到了如何让机器人在线程中响应而不是作为单个推文响应。我不是专家,但如果您有兴趣,请告诉我!

以上是关于如何发布超过 280 个字符的推文?因此,如果字符串 > 280,则打印前 280 个字符,然后在该线程中再次使用其余字符发送推文的主要内容,如果未能解决你的问题,请参考以下文章

Twitter:如何提取包含符号 (!,%,$) 的推文?

我怎样才能获得超过一周的推文(使用 tweepy 或其他 python 库)

我如何创建将单词添加到字符串python的循环

如何将 Twitter API 用于超过 REST 速率限制的大型 Web 应用程序

推特 140 个字符限制的 Twython

如何忽略已在 Tweepy 中转发的推文?