Twitter 不仅仅是一个延伸的新闻来源,它绝对是了解世界想法的最佳样本之一。它拥有超过 3.3 亿活跃用户,是人们喜欢分享自己想法的顶级平台之一。Twitter 数据可用于多种目的,例如 研究, 消费者洞察, 人口统计学洞察,以及更多。
因此,本教程的主要目的是教您如何获取与您的项目或业务相关的 Twitter 数据样本。
在继续之前,请确保您已准备好所有这些变量:
- Consumer Key
- Consumer Secret
- Access Token
- Access Token Secret
如果您想知道如何获取上述详细信息,请阅读 我的同事 Dattatray Upase 撰写的这篇博客文章.
现在让我们开始编写代码吧!
定义输入变量
首先,您需要定义程序所需的一些全局变量:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import sys start_date = sys.argv[1] #"2018-01-09" end_date = sys.argv[2] #"2018-01-10" consumerKey="Enter_Your_Consumer_Key_Here" consumerSecret="Enter_Your_Consumer_Secret_Here" accessToken="Enter_Your_Access_Token_Here" accessTokenSecret="Enter_Your_Access_Token_Secret_Here" keyword= sys.argv[3] #"tcs" lang="en" #see what twitter offers for language filtering data={} |
我正在导入 ‘sys’ 以获取命令行参数,因为我可能想要更改关键字、开始日期或结束日期。语言方面我选择了英语,但您可能需要检查支持的其他语言。结果最终将存储在 ‘data’ 中。
因此,该脚本的典型用法如下所示:
python script.py start_date end_date keyword
访问 Twitter API
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import oauth2 req_count = 0 def oauth_req(url, http_method="GET", post_body=b"", http_headers=None): global req_count,consumerKey,consumerSecret,accessToken,accessTokenSecret req_count += 1 consumer = oauth2.Consumer(key=consumerKey, secret=consumerSecret) token = oauth2.Token(key=accessToken, secret=accessTokenSecret) client = oauth2.Client(consumer, token) resp, content = client.request( url, method=http_method, body=post_body , headers=http_headers ) return content |
The req_count 变量是我在执行程序时使用 API 的次数。使用给定的代码时,我遇到了以下错误:
TypeError: Unicode-objects must be encoded before hashing
为了避免这种情况,我将 post_body=”” 修改为 post_body=b”” ,这解决了问题。
Twitter API 的使用和参考
是时候设置 API URL 来获取 Twitter 数据了。我正在使用参数 min_faves。以下是该 URL 的说明以及一些优化技巧:
‘min_faves’ 用于设置数据中推文应具有的最少收藏数。这是一个非常实用的功能,但 Twitter API 文档中并未提及。
‘q’ 代表您要输入的查询或关键词。在这里,确保提供尽可能少的关键词非常重要。例如,假设我想要关于 Facebook 和 Google 的推文。如果我将两者都作为关键词(比如 FACEBOOK 和 GOOGLE),由于限制,它最多只会返回 100 条推文。但如果我运行两次查询——一次用 Facebook,一次用 Google,我总共可以获得 200 条推文。长话短说,最好每个查询只使用一个关键词。
‘lang’ 代表过滤后的推文语言。因为我想获取英文推文,所以我将其设置为 ‘en’。
‘since’ 是您想要查找推文的时间段的开始日期。该开始日期应在过去 7 天内。这是另一个在 Twitter API 文档中未记录的功能。
‘until’ 代表您期望时间段的结束日期。从逻辑上讲,它也应该在过去 7 天内。它同样未在 Twitter API 文档中记录。
‘result_type’ 代表您想要的推文类型。它有 3 个值:
‘recent’ 提供最新的推文,即所选时间段结束时的推文。
‘popular’ 提供最热门的推文,因此会遗漏很多推文。您总是会获得获得最多收藏和转推的推文。 min_faves 功能在这里将毫无用处。
‘mixed’ 提供最新推文和热门推文的混合。
‘count’ 代表结果中的最大推文数量。默认设置为 15,最大值为 100。
通过混合的 result_type 以及使用 min_faves ,我们可以通过多次运行查询来获取最多的推文。
|
1 2 3 |
def get_tweets(min_faves): global keyword, start_date, end_date, lang return oauth_req( 'https://api.twitter.com/1.1/search/tweets.json?' + '&q=' + keyword + '&lang=' + lang + '%20since%3A' + start_date + '%20until%3A' + end_date + '%20min_faves%3A' + str(min_faves) +'&result_type=mixed&count=100') |
要了解更多已记录的功能,您还可以查看 Twitter 的 API 文档.
保存/自动保存获取的推文数据
下一步,您需要定义一个具有参数 ‘saveOverride’ 的自动保存/保存方法。此步骤仅用于移除自动保存时间限制并保存文件。为此,我创建了一个 t_last 来保存程序的启动时间。然后我在程序中访问它,并检查自 t_last (上次保存时间)以来是否已过去 5 分钟。如果已超过 5 分钟,我将 ‘saveStatus’ 标记为 True。
接下来,我检查 ‘saveOverride’,这简单来说意味着我需要向我的程序发出指令:无论如何,现在都应该保存文件。为此,我将 saveStatus 设置为 True。
然后,如果 ‘saveStatus’ 为 True,脚本将更改 t_last 为当前时间。之后,代码会创建一个字典对象并打印 “在 [time] 自动保存” ,以便您知道数据正在被自动保存。
接下来,我检查输出文件是否已存在。如果存在,我将合并当前数据与已保存文件中的数据。合并后,我将其写入同一个文件。如果不存在,我将创建一个新文件,然后将数据写入该文件。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import os import json import time import datetime t_last = time.time() def autosave(saveOverride = False): global t_last saveStatus = (time.time() > t_last + 300) if(saveOverride == True):en" saveStatus = True if(saveStatus): t_last=time.time() tmp = {} print("自动保存 在 " + str(datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S"))) fnamea = keyword + "-st-" + start_date + "-ed-"+ end_date + '.json' if os.path.exists(fnamea) == True: with open(fnamea,'r+') as f: tmp = json.load(f) for i in data.keys(): tmp[i] = data[i] with open(fnamea,'w+') as f: json.dump(tmp,f) |
因此,我几乎已经编写了所有我想要的功能。
进一步优化
最后,是时候使用这些函数了。我正在编写一个 while(1) 循环,这意味着 while(True)。这基本上会使指令永远运行,直到调用某个 ‘break’ 语句或引发某些异常。
首先,我使用 json.loads 将数据转换为字典格式。然后,我在 try-catch/except 提取数据的状态代码块上运行。我使用 try-catch 是因为有时 Twitter API 不返回数据,而是返回一个提到错误的 JSON。我不希望我的程序在这种情况下停止。此外,我希望它能检索到这是在第几次请求时发生的,并使用自动保存命令保存我的 Twitter 数据。Twitter 允许我们每 15 分钟发送 180 次请求。这相当于每分钟 12 次请求,或者每五秒一次请求。为了安全起见,我添加了一个 sleep 命令,使我的程序在执行一次迭代后休眠 5 秒。
之后,代码将显示该脚本目前已收集的推文数量。
最后,是时候使用主要的优化技巧了。我测试这个脚本将近一个星期,每个 min_faves 值都得到了以下数量 of 推文。我每次请求最多可以获取 100 条推文,并且我希望尽可能多地获取。目前,具有较高 min_faves 值的推文并不多,但我们希望考虑到公司或关键词可能处于趋势中的时候。 min_faves 的最大值可以是 999999。
| min_faves 值 | 推文数量 |
| 100,000 | 1 |
| 90,000 | 1 |
| 80,000 | 1 |
| 70,000 | 2 |
| 60,000 | 3 |
| 50,000 | 6 |
| 40,000 | 6 |
| 30,000 | 12 |
| 25,000 | 12 |
因此,我使用了一种逻辑,该逻辑将从 min_faves 值为 60000 开始获取推文,然后每次减少 10000,直到达到 10000。但是,如果说关键词很热门,并且当我的 min_faves 值为 30000 时获得了 100 条推文,它将增加 min_faves 至 35000,然后再次获取结果。所以现在新的逻辑是 5000 而不是 10000。然而,如果变化量减少到小于 1000,我要求它忽略并继续减去 1000。
我正在指定一个固定的间隔 1000,min_faves 应该减少,如果 min_faves 小于或等于 10000。
在程序结束时,程序将通过显示 ‘End’ 来让您知道工作已完成。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
min_faves=60000 change=10000 #大幅减少 min_faves 以提取数据 interval = 500 #正常减少 min_faves 以提取数据 while(1): d = json.loads(get_tweets(min_faves)) try: for i in d['statuses']: data[i['id']] = i c = len(d['statuses']) except Exception as e: print("Error at request : " + str(req_count)) autosave(True) print("At request: " + str(req_count) + " Total Tweets Collected: " + str(len(data)) + " with Min Faves: " + str(min_faves) ) if c==100 and min_faves>10000: if (change>1000): change /= 2 min_faves += change else: min_faves -= change elif min_faves>10000: min_faves -= change else: min_faves -= interval if(min_faves < 0): fnamea = keyword + '.json' autosave(True) break autosave() time.sleep(5) print("End") |
您可以在 GitHub.
以上就是全部内容。在下一个 Twitter 数据教程中,我将教您如何使用大数据工具 ‘Flume’ 获取实时推文。敬请关注!
评论
暂无评论。发表第一条评论吧。