You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

snscrape按日爬取Twitter主题推文仅获当日末段数据问题求解

问题根源

你拿到的推文全部集中在每日23:57左右,是两个问题导致的:

  1. snscrape的Twitter搜索默认按发布时间倒序返回结果,直接截取前100条,拿到的必然是距离until参数指定时间最近的内容,也就是当天最晚发布的一批推文
  2. 原代码存在缩进错误,爬取逻辑的for循环没有写在日期遍历的循环内部,实际执行逻辑和按天爬取的预期不符

方案1:按小时均匀采样(时段分布最均匀)

这个方案将单日拆分为24个独立的1小时时间窗口,每个窗口单独爬取固定数量的推文,彻底避免时段聚集。如果要实现你提到的每小时10条的采样粒度,只需要把daily_target参数改成240即可,示例默认按你原本单日100条的需求配置,每小时分配4-5条爬取配额,保证全天均匀分布。

import pandas as pd
import snscrape.modules.twitter as sntwitter
from datetime import datetime, timedelta

# 爬取参数配置
start_date = datetime(2022, 5, 1)  # 爬取起始日期
total_days = 31  # 总爬取天数
daily_target = 100  # 单日目标爬取量,要实现每小时10条就把这个值改成240
hourly_target = daily_target // 24
tweets_list = []

for day_offset in range(total_days):
    current_date = start_date + timedelta(days=day_offset)
    print(f"正在爬取日期:{current_date.date()}")
    collected_today = 0

    # 遍历当天24个小时窗口
    for hour in range(24):
        window_start = current_date + timedelta(hours=hour)
        window_end = window_start + timedelta(hours=1)
        # 构造带时分秒的精确检索条件
        query = f'bitcoin since:{window_start.strftime("%Y-%m-%dT%H:%M:%S")} until:{window_end.strftime("%Y-%m-%dT%H:%M:%S")}'
        
        hour_collected = 0
        for tweet in sntwitter.TwitterSearchScraper(query).get_items():
            if hour_collected >= hourly_target:
                break
            tweets_list.append([tweet.date, tweet.content])
            hour_collected += 1
            collected_today +=1
        
        # 最后一个窗口补爬,凑够当日目标数量
        if hour == 23 and collected_today < daily_target:
            for tweet in sntwitter.TwitterSearchScraper(query).get_items():
                if collected_today >= daily_target:
                    break
                tweets_list.append([tweet.date, tweet.content])
                collected_today +=1

tweets_df = pd.DataFrame(tweets_list, columns=['Datetime', 'Text'])

方案2:全时段随机抽样

如果不需要严格按小时均匀分布,想要实现全天随机取样,可以把单日拆成更细的时间窗口,随机抽取窗口爬取,样本会随机覆盖全天各个时段,效率也比爬取全量当日推文后抽样更高。

import pandas as pd
import snscrape.modules.twitter as sntwitter
from datetime import datetime, timedelta
import random

# 爬取参数配置
start_date = datetime(2022, 5, 1)
total_days = 31
daily_target = 100
window_minutes = 10  # 按10分钟拆分时间窗口,单日共144个窗口
tweets_list = []

for day_offset in range(total_days):
    current_date = start_date + timedelta(days=day_offset)
    print(f"正在爬取日期:{current_date.date()}")
    
    # 生成当日所有时间窗口,随机选daily_target个窗口爬取
    total_windows = 24 * 60 // window_minutes
    selected_windows = random.sample(range(total_windows), daily_target)

    for win_idx in selected_windows:
        window_start = current_date + timedelta(minutes=win_idx * window_minutes)
        window_end = window_start + timedelta(minutes=window_minutes)
        query = f'bitcoin since:{window_start.strftime("%Y-%m-%dT%H:%M:%S")} until:{window_end.strftime("%Y-%m-%dT%H:%M:%S")}'
        
        # 每个选中的窗口取1条推文
        for tweet in sntwitter.TwitterSearchScraper(query).get_items():
            tweets_list.append([tweet.date, tweet.content])
            break

tweets_df = pd.DataFrame(tweets_list, columns=['Datetime', 'Text'])

注意事项
  • 代码里的时间默认用UTC时区计算,如果需要对齐国内时区,给时间对象加上8小时偏移即可
  • 如果个别时间窗口内比特币相关推文数量不足,代码会自动跳过,不会卡住,最终爬取总量可能和目标值有极小幅偏差,如果偏差明显可以把时间窗口粒度调得更细
  • 爬取过程中建议在每个请求间隔加1-2秒的随机延时,避免触发平台的访问频率限制

内容的提问来源于stack exchange,提问作者Jacopo Giannetti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 22:06:18