将推文存储到csv文件中时出现问题

时间:2019-03-07 15:42:09

标签: python csv twitter twython

我正在与Python一起尝试将与特定关键字相关的推文(更确切地说,仅是日期,用户,个人简介和文本)存储在csv文件中。 当我使用Twitter的免费API时,每15分钟只能发送450条推文。 因此,我编写了一些代码,应该在15分钟内准确存储450条推文。

问题是提取推文时出现问题,因此在特定点一次又一次存储同一推文。

任何帮助将不胜感激! 预先感谢

import time
from twython import Twython, TwythonError, TwythonStreamer
twitter = Twython(CONSUMER_KEY, CONSUMER_SECRET) 

sfile = "tweets_" + keyword + todays_date + ".csv"
id_list = [last_id]  
count = 0
while count < 3*60*60*2: #we set the loop to run for 3hours

    # tweet extract method with the last list item as the max_id
    print("new crawl, max_id:", id_list[-1])
    tweets = twitter.search(q=keyword, count=2, max_id=id_list[-1])["statuses"]
    time.sleep(2) ## 2 seconds rest between api calls (450 allowed within 15min window)

    for status in tweets:
        id_list.append(status["id"]) ## append tweet id's

        if status==tweets[0]:
            continue

        if status==tweets[1]:
            date = status["created_at"].encode('utf-8')
            user = status["user"]["screen_name"].encode('utf-8') 
            bio = status["user"]["description"].encode('utf-8')
            text = status["text"].encode('utf-8')

            with open(sfile,'a') as sf:
                sf.write(str(status["id"])+ "|||" + str(date) + "|||" + str(user) + "|||" + str(bio) + "|||" + str(text)  +  "\n")

        count += 1
        print(count)
        print(date, text)

1 个答案:

答案 0 :(得分:0)

您应该使用Python的CSV库编写CSV文件。它获取包含一行所有项目的列表,并自动为您添加定界符。如果值包含逗号,它将自动为您添加引号(这就是CSV文件的工作方式)。它甚至可以处理值中的换行符。如果将结果文件打开到电子表格应用程序中,您将看到已正确读取文件。

更好的方法是使用绝对时间,而不是尝试使用time.sleep()。因此,我们的想法是花费您的开始时间,并增加三个小时。然后,您可以继续循环播放,直到达到finish_time

可以对您的API调用分配采取相同的方法。保留一个计数器,记下您还有多少个电话,并将其减少计数。如果到达0,则停止拨打电话,直到到达下一个15分钟的时段。

timedelta()可用于向现有datetime对象添加分钟或数小时。通过这种方式,您的时间将永远不会失步。

以下显示了如何使事情正常运行的模拟。您只需要添加回代码即可获取推文:

from datetime import datetime, timedelta
import time
import csv
import random   # just for simulating a random ID

fifteen = timedelta(minutes=15)
finish_time = datetime.now() + timedelta(hours=3)

calls_allowed = 450
calls_remaining = calls_allowed

now = datetime.now()
next_allocation = now + fifteen

todays_date = now.strftime("%d_%m_%Y")
ids_seen = set()

with open(f'tweets_{todays_date}.csv', 'w', newline='') as f_output:
    csv_output = csv.writer(f_output)

    while now < finish_time:
        time.sleep(2)
        now = datetime.now()

        if now >= next_allocation:
            next_allocation += fifteen
            calls_remaining = calls_allowed
            print("New call allocation")

        if calls_remaining:
            calls_remaining -= 1
            print(f"Get tweets - {calls_remaining} calls remaining")

            # Simulate a tweet response
            id = random.choice(["1111", "2222", "3333", "4444"])    # pick a random ID
            date = "01.01.2019"
            user = "Fred"
            bio = "I am Fred"
            text = "Hello, this is a tweet\nusing a comma and a newline."

            if id not in ids_seen:
                csv_output.writerow([id, date, user, bio, text])
                ids_seen.add(id)

关于继续写相同的推文的问题。您可以使用set()来保存所有已写入的ID。然后,您可以在重新编写之前测试是否已经看到新的推文。