【问题标题】:Query Instagram posts by hashtag and time range按标签和时间范围查询 Instagram 帖子
【发布时间】:2015-11-24 10:22:39
【问题描述】:

我正在尝试通过提供主题标签和时间范围(自和直到日期)来查询来自 Instagram 的帖子。 我使用recent tags endpoint

https://api.instagram.com/v1/tags/{tag-name}/media/recent?access_token=ACCESS-TOKEN

我的代码是使用 instagram-node 库在 Node.js 中编写的(请参阅内联 cmets):

// Require the config file
var config = require('../config.js');

// Require and intialize the instagram instance
var ig = require('instagram-node').instagram();

// Set the access token
ig.use({ access_token: config.instagram.access_token });

// We export this function for public use
// hashtag: the hashtag to search for
// minDate: the since date
// maxDate: the until date
// callback: the callback function (err, posts)
module.exports = function (hashtag, minDate, maxDate, callback) {

  // Create the posts array (will be concated with new posts from pagination responses)
  var posts = [];

  // Convert the date objects into timestamps (seconds)
  var sinceTime = Math.floor(minDate.getTime() / 1000);
  var untilTime = Math.floor(maxDate.getTime() / 1000);

  // Fetch the IG posts page by page
  ig.tag_media_recent(hashtag, { count: 50 }, function fetchPosts(err, medias, pagination, remaining, limit) {

    // Handle error
    if (err) {
      return callback(err);
    }

    // Manually filter by time
    var filteredByTime = medias.filter(function (currentPost) {
      // Convert the created_time string into number (seconds timestamp)
      var createdTime = +currentPost.created_time;

      // Check if it's after since date and before until date
      return createdTime >= sinceTime && createdTime <= untilTime;
    });

    // Get the last post on this page
    var lastPost = medias[medias.length - 1] || {};

    // ...and its timestamp
    var lastPostTimeStamp = +(lastPost.created_time || -1);

    // ...and its timestamp date object
    var lastPostDate = new Date(lastPostTimeStamp * 1000);

    // Concat the new [filtered] posts to the big array
    posts = posts.concat(filteredByTime);

    // Show some output
    console.log('found ' + filteredByTime.length + ' new items total: ' + posts.length, lastPostDate);


    // Check if the last post is BEFORE until date and there are no new posts in the provided range
    if (filteredByTime.length === 0 && lastPostTimeStamp <= untilTime) {
      // ...if so, we can callback!
      return callback(null, posts);
    }

    // Navigate to the next page
    pagination.next(fetchPosts);
  });
};

这将开始获取最近到最近的帖子,并手动过滤created_time。 这行得通,但是效率非常低,因为例如,如果我们想要获取一年前的帖子,我们必须迭代页面直到那个时候,这将使用大量请求(可能超过 5k/小时这是速率限制)。

有没有更好的方法来进行这个查询?如何通过提供标签和时间范围来获取 Instagram 帖子?

【问题讨论】:

  • 您能否只增加count 以一次抓取更多的照片以减少数量 的帖子获取?当然它们会更大,但这样的东西会有用吗?
  • @NickZ 我们确实尝试过这样做(我正在调试这是 OP),我们得到的最大值是 33 个项目/请求。所以,count 并没有真正的帮助...... :-( 还有其他想法吗?我很高兴将 50 分奖励给给出好的答案的人。:D
  • 您是否考虑过使用 MIN_TAG_ID 和 MAX_TAG_ID 快速迭代到目标日期?我可以想象一种方法,它一次只查询一个帖子,以找到恰好在所需日期之前的 MAX_TAG_ID。
  • 看到没有引用任何参数,您需要根据响应进行此过滤。抓取数据并丢弃不需要的数据是不可接受的吗?
  • @sbozzie 是的,这可能就是 pagination.next 在内部所做的。但这与日期无关(或者是吗?)。如果您发现日期和标签 id 之间存在关系,那就太好了(例如,21 March 2013 被转换为标签 id,使用该标签 id 将获取从该日期开始的帖子)。我猜标签 id 只是一个内部 id,但我不确定。

标签: javascript node.js api instagram instagram-api


【解决方案1】:

我认为这是您正在寻找的基本理念。我对 Node.js 并不太熟悉,所以这都是纯 javascript。您必须对其进行修改以满足您的需要,并可能利用它来实现功能。

我们的想法是将 instagram id(在此示例中为 1116307519311125603)转换为日期,反之亦然,以使您能够快速获取特定时间点,而不是回溯所有结果,直到找到所需的时间戳。下划线 '_' 之后的 id 部分应该被剪掉,因为它以某种方式指向用户 IIRC。示例中有 4 个函数,希望对您有所帮助。

黑客愉快!

//static
var epoch_hour = 3600,
    epoch_day = 86400,
    epoch_month = 2592000,
    epoch_year = 31557600;

//you'll need to set this part up/integrate it with your code
var dataId = 1116307519311125603,
    range = 2 * epoch_hour,
    count = 1,
    tagName = 'cars',
    access = prompt('Enter access token:'),
    baseUrl = 'https://api.instagram.com/v1/tags/' + 
              tagName + '/media/recent?access_token=' + access;

//date && id utilities
function idToEpoch(n){
  return Math.round((n / 1000000000000 + 11024476.5839159095) / 0.008388608);
}

function epochToId(n){
  return Math.round((n * 0.008388608 - 11024476.5839159095) * 1000000000000);
}

function newDateFromEpoch(n){
  var d = new Date(0);
  d.setUTCSeconds(n);
  return d;
}

function dateToEpoch(d){
  return (d.getTime()-d.getMilliseconds())/1000;
}

//start with your id and range; do the figuring
var epoch_time = idToEpoch(dataId),
    minumumId = epochToId(epoch_time),
    maximumId = epochToId(epoch_time + range),
    minDate = newDateFromEpoch(epoch_time),
    maxDate = newDateFromEpoch(epoch_time + range);

var newUrl = baseUrl + 
             '&count=' + count + 
             '&min_tag_id=' + minumumId + 
             '&max_tag_id=' + maximumId;


//used for testing
/*alert('Start: ' + minDate + ' (' + epoch_time + 
        ')\nEnd: ' + maxDate + ' (' + (epoch_time +
        range) + ')');
window.location = newUrl;*/

【讨论】:

  • 这看起来棒极了!我现在正在测试它——你能解释一下这些神奇的数字吗:return Math.round((n * 0.008388608 - 11024476.5839159095) * 1000000000000);
  • 在哪里找到 Instagram 如何编码 id 的参考资料会很有用。这闻起来像未记录的功能。
  • 老实说,我今天创建了一个 instagram 帐户只是为了使用他们的 API 控制台。确定(实际上是近似)编码只需要一点逆向工程。我发现的任何地方都没有记录它。 :(
  • 找到文档! instagram-engineering.tumblr.com/post/10853187575/…公平地说,这是一篇博文,但它仍然是“官方的”
  • 不幸的是,这正式不再起作用。 Instagram 开始散列他们的 max_tag_id 并停止支持 min_tag_id
【解决方案2】:

为支持this优秀答案,通过plpgSQL函数生成一个instagram ID:

CREATE OR REPLACE FUNCTION insta5.next_id(OUT result bigint) AS $$
DECLARE
    our_epoch bigint := 1314220021721;
    seq_id bigint;
    now_millis bigint;
    shard_id int := 5;
BEGIN
    SELECT nextval('insta5.table_id_seq') %% 1024 INTO seq_id;

    SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
    result := (now_millis - our_epoch) << 23;
    result := result | (shard_id << 10);
    result := result | (seq_id);
END;
$$ LANGUAGE PLPGSQL;

来自Instagram's blog

【讨论】:

    【解决方案3】:

    尽管有类似的获取帖子过程,但我目前工作的 Data365.co Instagram API 似乎更适合和高效。它没有每小时 5,000 个帖子的限制,您可以在请求本身中指定您需要发布的时间段。此外,计费将仅考虑指定期间的帖子。您无需为不需要的数据付费。

    您可以在下面看到一个任务示例,以下载 2021 年 1 月 1 日至 2021 年 1 月 10 日期间的主题标签比特币帖子。

    POST 请求:https://api.data365.co/v1.1/instagram/tag/bitcoins/update?max_posts_count=1000&from_date=2021-01-01&to_date=2021-01-10&access_token=TOKEN

    获取相应帖子列表的 GET 请求示例: https://api.data365.co/v1.1/instagram/tag/bitcoins/posts?from_date=2021-01-01&to_date=2021-01-10&max_page_size=100&order_by=date_desc&access_token=TOKEN

    API 文档中的更详细信息视图https://api.data365.co/v1.1/instagram/docs#tag/Instagram-hashtag-search

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 2019-11-26
      • 1970-01-01
      相关资源
      最近更新 更多