往日微忆

用 grailbird_update 更新备份 Twitter 我的存档包(见 https://www.yiwan.org/index.php/ltd_documents/384-use-grailbird_update-to-backup-tweets.html 文章和我的 Github 仓库 extract-tweets: https://github.com/litanid/extract-tweets ),总是感觉不是那么可靠,毕竟获取 tweets 过程对自己是透明的,不能完全由自己掌握,而且 grailbird_update  更新获取的 tweets 数据或多或少有那么点不足,如 tweet text 内容默认不显示全部,如果内容字数较多;还有 tweet 里本来就有图片,但获取的数据里没有包含;由于时间差的原因,获取的以年月命名的数据文件,有时下个月的数据保存在这个月里;诸如还有较多,暂不细述。我想要的是,给定时间段,就获取这个时间段内的 tweets 数据,text 内容全部显示,其他信息可能由于 twitter 的限制,不能获取那是没办法的事。

于是,有了我的 repository:retrieve-tweets (https://github.com/litanid/retrieve-tweets)。

库里代码文件 get-tweets_by_AndyPatel.py 是 Andy Patel 在博文《How To Get Tweets From A Twitter Account Using Python And Tweepy》(https://labsblog.f-secure.com/2018/01/26/how-to-get-tweets-from-a-twitter-account-using-python-and-tweepy/) 的代码。我改写的代码文件 retrieve-tweets-using-tweepy_by_litanid.NK.py 主要参考了这篇文章。

retrieve-tweets-using-tweepy_by_litanid.NK.py 用 python3 编写,利用 tweepy 库连接 Twitter API 获取 tweets 。文件代码比较简单,一看即懂。

from datetime import datetime,timezone,timedelta
import sys
import tweepy
import re
import os
import json


beginday = sys.argv[1]
endday = sys.argv[2]
beginday_datetime_string = beginday + " 00:00:00"  #起始日期当天的0点0分0秒
endday_datetime_string = endday + " 23:59:59"  #结束日期为当天的23点59分59秒
outputFile_name0 = beginday + "-" + endday  #输出文件名
outputFile_name1 = ".js"  #输出文件扩展名
outputFile_name = outputFile_name0 + outputFile_name1

#转换成datetime类型
beginday_datetime = datetime.strptime(beginday_datetime_string,'%Y-%m-%d %H:%M:%S')
endday_datetime = datetime.strptime(endday_datetime_string,'%Y-%m-%d %H:%M:%S')

#北京时间转换成格林尼治时间UTC
beginday_datetime_beijing = beginday_datetime.replace(tzinfo=timezone(timedelta(hours=8))) #输入时间确定为北京时间
endday_datetime_beijing = endday_datetime.replace(tzinfo=timezone(timedelta(hours=8))) #输入时间确定为北京时间
beginday_datetime_utc = beginday_datetime_beijing.astimezone(timezone.utc) #转换为utc时间
endday_datetime_utc = endday_datetime_beijing.astimezone(timezone.utc) #转换为utc时间
beginday_datetime_utc = beginday_datetime_utc.replace(tzinfo=None) #时间转换成为offset-naive才能进行比较
endday_datetime_utc = endday_datetime_utc.replace(tzinfo=None) #时间转换成为offset-naive才能进行比较

consumer_key = ''
consumer_secret = ''
access_token = ''
access_secret = ''

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)
 
api = tweepy.API(auth)
#如果被墙,可以采用代理  auth_api = API(auth,proxy="127.0.0.1:1080")

tweets = []
for tweet in tweepy.Cursor(api.user_timeline,tweet_mode="extended").items():
  '''
      Cursor(auth_api.user_timeline, id=target)其他一些参数 
      screen_name = screen_name,count=200, tweet_mode="extended"
      Instead of full_text=True you need tweet_mode="extended"
      Then, instead of text you should use full_text to get the full tweet text.
      tweets = [[tweet.full_text] for tweet in new_tweets]

      tweets = []
        for tweet in tweepy.Cursor(api.user_timeline,
                           screen_name=<twitter_handle>,
                           since_id = <since_id>
                           ).items(<count>):
            tweets.append(tweet)
  '''
  if tweet.created_at >= beginday_datetime_utc and tweet.created_at <= endday_datetime_utc :
    tweets.append(tweet._json)

with open(outputFile_name,'w') as outputFile:
    print("Grailbird.data.tweets_{0} =".format(outputFile_name0),file = outputFile)
    tweets_output = json.dumps(tweets, sort_keys=True, indent=4, separators=(',', ':'))
    tweets_output = re.sub('"full_text":"','"text":"',tweets_output)  #获取tweet推文全部内容
    print(tweets_output,file = outputFile)   
    #格式化输出json字符串

运行此文件,需要提供初始日期和结束日期,如:

python3 retrieve-tweets-using-tweepy_by_litanid.NK.py 2018-01-01 2018-01-31

则将获取北京时间2018年1月1日00:00:00至2018年1月31日23:59:59之间的推文数据,生成 2018-01-01-2018-01-31.js 文件,可以使用 extract-tweets (https://github.com/litanid/extract-tweets) 中的 extract-tweets-to-md_by_litanid_after.py 进行处理输出为 Markdown 文件。