使用 Twitter API 让你的通勤更轻松
设置
处理凭证
使用高级 30 天搜索 API
设置触发词和通知
使用 POST 状态/更新端点在 Twitter 上发帖
使用 DigitalOcean 部署您的应用程序
使用 Cron 安排你的应用自动运行
结论
本教程的代码可在 GitHub 上找到。
我每天都乘坐伦敦交通局的大都会线上下班。及时了解线路中断情况能帮我节省不少时间。幸运的是,大都会线的官方推特账号@metline会及时更新线路状态信息。
我原本为@metline账号启用了通知功能,这样每次@metline发新推文时,我的手机都会收到推送通知。但最终我收到了太多通知,而且很多都与我无关。
我需要一种方法来过滤感兴趣的推文,并且只接收与我的个人通勤模式相关的信息的通知。
输入...🥁🥁🥁 Twitter API!
我们将使用两个不同的端点:
-
高级30 天搜索 API(您可以免费使用沙盒版本)来查找我们感兴趣的推文。
-
POST状态/更新端点用于创建新推文,通知您潜在的中断。此端点免费提供。
设置
为了复制此应用程序,您将需要以下内容:
-
选择一个发布您感兴趣的信息的 Twitter 帐户。
在本例中,我们将使用@metline来发布地铁线路信息。 -
通知接收者(也就是通勤者)的 Twitter 账号。我使用了我的常用 Twitter 账号 ( @AureliaSpecker )。
-
通知发送者的 Twitter 账户。为此,我使用了辅助 Twitter 账户 ( @maddie_testing )。
-
Twitter 开发者账号:如果您还没有,可以申请一个。开发者账号需要与通知发送者的 Twitter 账号关联(本例中为@maddie_testing)。
-
访问您在上一步中创建的应用程序的密钥和令牌。
-
将“搜索推文:30 天沙盒”的开发环境设置为dev或prod 之类的。
-
Python 版本 3.6 或更高版本(在命令行中,您可以通过运行来检查安装了哪个版本的 Python
$ python --version
)。
从命令行为您的项目创建一个新目录。
$ mkdir commute-alerts
导航到其中并创建以下两个文件:
$ cd commute-alerts
$ touch alerts.py
$ touch credentials.yaml
此时,您的项目树应该看起来像这样(您可以使用安装树,$ sudo install tree
然后使用它$ tree
来获取以下输出):
└── alerts.py
└── credentials.yaml
如果您计划将项目推送到 GitHub,您还应该.gitignore
在项目目录中添加一个文件:
$ touch .gitignore
妥善保管您的访问密钥和令牌至关重要,因为它们代表着您对 Twitter API 的唯一访问权限。将它们保存在单独的文件 (credentials.yaml) 中,可以确保您从源头上排除它们,防止他人窃取。请务必将以下行添加到您的.gitignore
文件中:
credentials.yaml
通过在命令行中运行以下命令来检查是否已安装必要的依赖项:
$ pip install searchtweets
$ pip install requests_oauthlib
$ pip install pandas
alerts.py
在您喜欢的代码编辑器中打开(我使用Visual Studio Code)并添加以下代码行以导入所需的模块:
from searchtweets import ResultStream, gen_rule_payload, load_credentials, collect_results
from requests_oauthlib import OAuth1Session
import yaml
import json
import datetime as dt
import pandas as pd
处理凭证
现在打开credentials.yaml
并按照以下格式添加您的访问密钥和令牌。将{ENV}替换为您之前创建的开发环境名称,并相应地为每个字段插入访问密钥和令牌。
search_tweets_api:
account_type: premium
endpoint: https://api.twitter.com/1.1/tweets/search/30day/{ENV}.json
consumer_key: XXXXXXXXXX
consumer_secret: XXXXXXXXXX
access_token: XXXXXXXXXX
access_token_secret: XXXXXXXXXX
返回alerts.py
,使用load_credentials
Search Tweet Python 包装器。这将自动为您处理凭据:
creds = load_credentials(filename="./credentials.yaml",
yaml_key="search_tweets_api",
env_overwrite=False)
对于 POST 状态/更新端点,我们将手动加载凭证并将其存储到一组新变量中。
with open('./credentials.yaml') as file:
data = yaml.safe_load(file)
consumer_key = data["search_tweets_api"]["consumer_key"]
consumer_secret = data["search_tweets_api"]["consumer_secret"]
access_token = data["search_tweets_api"]["access_token"]
access_token_secret = data["search_tweets_api"]["access_token_secret"]
然后我们将使用OAuth1Session来管理凭据:
oauth = OAuth1Session(
consumer_key,
client_secret=consumer_secret,
resource_owner_key=access_token,
resource_owner_secret=access_token_secret,
)
使用高级 30 天搜索 API
此端点允许您访问过去 30 天的 Twitter 数据。您可以在Twitter 开发者文档中了解有关此端点的更多信息。
此端点采用四个不同的参数:
- 询问
- 起始日期
- 迄今为止
- maxResults(换句话说,每次调用返回的结果数)。
我们将使用Python 的 datetime 模块生成 fromDate 和 toDate ,并设定一个时间范围,以便搜索来自@metline的推文。在本例中,我们想要查找过去两小时内发布的所有推文。请注意,Twitter API 中的时间是 UTC 时间。将以下代码行添加到 中alerts.py
:
utc = dt.datetime.utcnow() + dt.timedelta(minutes=-1)
utc_time = utc.strftime("%Y%m%d%H%M")
print("toDate:", utc_time)
two_hours = dt.datetime.utcnow() + dt.timedelta(hours=-2, minutes=-1)
two_hours_prior = two_hours.strftime("%Y%m%d%H%M")
print("fromDate:", two_hours_prior)
$ python alerts.py
当您在命令行中运行时,这将返回类似这样的内容(这是 toDate 和 fromDate 参数所需的格式):
toDate: 201910071658
fromDate: 201910071458
搜索推文 Python 包装器使我们能够使用 30Day Search 端点,而无需进行过多设置。在本例中,我们希望获取来自@metline的所有推文,且不包含任何提及其他 Twitter 帐户的内容。因此,我们的查询语句为“from:metline -has:mentions”。您可以在Twitter 开发文档中阅读更多关于构建查询的信息。我们还希望每次调用返回的推文不超过 100 条(这是我们在免费沙盒访问下可以返回的最大数量)。
rule = gen_rule_payload("from:metline -has:mentions",from_date=str(two_hours_prior), to_date=str(utc_time), results_per_call=100)
print("rule:", rule)
这里,打印函数将返回如下内容:
rule: {"query": "from:metline -has:mentions", "maxResults": 100, "toDate": "201910071658", "fromDate": "201910071458"}
我们将此查询返回的推文存储在新变量“tweets”中,然后使用列表推导打印出查询返回的前 10 行推文:
tweets = collect_results(rule,
max_results=100,
result_stream_args=creds)
[print(tweet.created_at_datetime, tweet.all_text, end='\n\n') for tweet in tweets[0:10]];
这将返回类似以下内容。请注意,如果前两个小时内没有创建任何推文,则不会返回任何内容。
2019-10-07 05:06:17 Minor delays between Uxbridge and Harrow-on-the-Hill, southbound only, due to a temporary shortage of train operators. Good service on the rest of the line.
2019-10-07 04:36:30 Minor delays between Harrow-on-the-Hill and Watford / Rayners Lane northbound only due to the temporary unavailability of train operators. Good service on the rest of the line.
2019-10-06 22:27:02 A good service is now operating to all destinations.
2019-10-06 21:49:52 Minor delays between Chesham/Amersham and Rickmansworth, southbound only, due to a signal failure at Chalfont & Latimer.
设置触发词和通知
我们需要确定哪些词语会触发通勤者的通知。我们将使用Python 集来实现这一点。
在这个例子中,有两个通勤者:David 和 Aurelia。某些词语会触发两个通勤者的通知,而其他词语只会触发其中一位通勤者的通知。
all_trigger = {'closure', 'wembley', 'delays', 'disruption', 'cancelled', 'sorry', 'stadium'}
david_trigger = {'hillingdon', 'harrow'}
aurelia_trigger = {'baker'}
请注意,如果您想在这些集合中添加由两个单词组成的字符串,则必须使用RE添加额外的数据处理级别(本教程中不包含此内容)。
接下来,我们创建两个新列表来存储上述调用返回的推文日期和推文文本:
tweet_text = []
tweet_date = []
我们还希望将前两个小时的推文中包含的所有单词连接成一个字符串:
combined_tweet_text = ' '
然后,我们使用For 循环来填充我们用推文文本和推文日期创建的列表,并将来自不同推文的文本连接成一个字符串。
for tweet in tweets:
tweet_text.append(tweet.all_text)
tweet_date.append(tweet.created_at_datetime)
combined_tweet_text += tweet.all_text
以下行创建一个新集合,其中包含过去两小时内创建的推文中的所有小写单词:
tweet_words = set(combined_tweet_text.lower().split())
然后,我们使用If 语句以及 Python len() 函数和setintersection() 方法来定义是否必须发送通知:
if len(tweet_words.intersection(all_trigger)) != 0:
message = "@AureliaSpecker & @_dormrod 👋 check https://twitter.com/metline for possible delays, [{}]".format(utc_time)
elif len(tweet_words.intersection(david_trigger)) != 0:
message = "@_dormrod 👋 Check https://twitter.com/metline for possible delays, [{}]".format(utc_time)
elif len(tweet_words.intersection(aurelia_trigger)) != 0:
message = "@AureliaSpecker 👋 Check https://twitter.com/metline for possible delays, [{}]".format(utc_time)
else:
message = "There are no delays"
pass
您可以打印消息输出,以检查运行时是否返回了正确的信息$ python alerts.py
:
print("Message:", message)
使用 POST 状态/更新端点在 Twitter 上发帖
最后一步是,当触发词之一出现在推文文本中时,以新推文的形式发送通知。
我们使用 Twitter 的POST 状态/更新端点,并将参数“status”(即推文正文)设置为上面定义的变量“message”:
params = {"status": message}
oauth.post(
"https://api.twitter.com/1.1/statuses/update.json", params=params
)
只要接收 Twitter 帐户启用了通知,每次他们的 @username 包含在推文正文中时,通勤者都会收到通知。
使用 DigitalOcean 部署您的应用程序
我选择使用DigitalOcean将此应用程序部署到远程服务器。
-
登录您的 DigitalOcean 帐户(或注册一个)
-
创建一个新项目,然后在该项目内,通过选择右上角的“创建”来创建一个新的 droplet。这里有一个关于如何创建新 droplet 的优秀教程。
Droplet 是基于 Linux 的虚拟机。换句话说,您创建的每个 Droplet 都充当一个可用于部署项目的新服务器。
- 创建 Droplet 后,您需要连接到该 Droplet。本教程将讲解如何操作。
连接到 Droplet(即连接到服务器)后,您需要将项目上传到该服务器。您可以将 Droplet(或服务器)视为另一台本地计算机,通过从 GitHub 克隆代码库来添加项目。
-
如果您还没有这样做,请按照本教程将您的项目添加到 GitHub 。请务必按照上述说明将您的
credentials.yaml
文件添加到您的文件中。切记不要意外将任何凭据推送到 GitHub。查看本指南,了解如何保护您的密钥和访问令牌。.gitignore
-
本文介绍如何克隆 GitHub 存储库。
-
添加项目后,您必须创建一个新
credentials.yaml
文件(就像您之前创建的文件一样)并将其保存在项目文件夹中。您可以使用vim或nano作为文本编辑器将您的凭据添加到文件中:
# touch credentials.yaml
# vim credentials.yaml
键入ESC:wq保存更改并退出 VIM 模式。
- 还要确保添加一个
.gitignore
文件并添加credentials.yaml
到该文件,以确保您不会意外提交任何访问密钥和令牌:
# touch .gitignore
# vim .gitignore
再次,您可以使用ESC :wq保存更改并退出 VIM 模式。
- 展望未来,如果您想从 GitHub 中提取任何更改,您可以在项目目录中运行以下命令:
# git pull
-
然后,安装所有必需的依赖项(如前所述),就像在另一台本地计算机上一样。
-
您现在可以运行您的应用程序了:
# python3 alerts.py
恭喜!🥳 您的应用现已安装在远程服务器上。
使用 Cron 安排你的应用自动运行
Cron 允许你安排应用在特定日期的特定时间自动运行。例如,我只想alerts.py
在工作日的早上 6:30 和下午 4:30 运行。
我使用以下教程来学习如何设置 Cron 作业:
以下是我遵循的步骤:
- 在远程服务器上,
alerts.py
使用 vim 打开并将两个提及更改./credentials.yaml
为root/met-line-alerts/credentials.yaml
- 安装 crontab-python:
$ pip install python-crontab
- 创建一个新文件
cron.txt
并用vim打开:
# touch cron.txt
# vim cron.txt
- 在该文件中,添加以下行(在 vim 中键入字母“i”以插入文本):
30 6,16 * * 1-5 python3 /root/met-line-alerts/alerts.py
使用ESC :wq保存并退出 vim 模式
这行代码基本上告诉 Cronpython3 /root/met-line-alerts/alerts.py
从星期一到星期五,每周每天的 6 点 16 分 30 秒执行命令。
您可以在此网站上检查您的 Cron 计划表达式:https://crontab.guru/
你还应该检查 Linux 远程服务器上的时间,以确保你设置的时区是正确的。你可以输入 date 命令来执行此操作:# date
- 运行以下命令启动 Cron 作业:
# crontab cron.txt
- 您可以使用以下方式列出您的活跃 Cron 作业:
# crontab -l
- 您可以使用以下方式删除现有的 Cron 作业:
# crontab -r
结论
希望本教程能启发您使用 Twitter API 解决日常生活中的问题。除了 Twitter API 之外,我还使用了其他一些库和服务来编写本教程,但您可能有不同的需求,需要评估这些工具是否适合您。
如果您对本文有任何启发,欢迎在Twitter 社区论坛或通过@TwitterDev发推文告诉我们。您也可以在我们的反馈平台上提供反馈。
文章来源:https://dev.to/xdevs/using-the-twitter-api-to-make-your-commute-easier-3od0