2015-11-24 4 views
11

Я пытаюсь запрашивать сообщения из Instagram, предоставляя хэштег и временной диапазон (начиная с и до дат). Я использую recent tags endpoint.Записи в Instagram от hashtag и временного диапазона

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

Мой код написан на Node.js с помощью instagram-node библиотеки (см инлайн комментарии):

// 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. Это работает, но это очень неэффективно, потому что, если мы хотим, например, получать сообщения от года назад, мы должны итерации страниц до тех пор, и это будет использовать множество запросов (вероятно, более 5 к/час, который является пределом скорости).

Есть ли лучший способ сделать этот запрос? Как получить сообщения Instagram, предоставив хэштег и временной диапазон?

+0

Не могли бы вы просто увеличить 'count' захватить значительно большее количество фотографии за раз, чтобы уменьшить * количество * почтовых выборок? Конечно, они были бы намного больше, но что-то вроде этого было бы полезно? –

+0

@NickZ Мы пытались это сделать (я отлаживал это OP), и мы получили максимум 33 элемента/запроса. Итак, 'count' на самом деле не помогает ... :-(Любые другие идеи? Я рад предоставить 50 баллов тому, кто дает хороший ответ.: D –

+1

Вы изучали использование MIN_TAG_ID и MAX_TAG_ID для итерация быстро к намеченной дате? Я могу представить себе метод, который запрашивал бы только одно сообщение за раз, чтобы найти MAX_TAG_ID, который находится непосредственно перед датой. – sbozzie

ответ

6

Я думаю, что это основная идея, которую вы ищете. Я не слишком знаком с Node.js, так что все это на простом javascript. Вам придется изменить его в соответствии с вашими потребностями и, возможно, сделать из него функцию.

Идея состоит в том, чтобы преобразовать идентификатор instagram (1116307519311125603 в этом примере) на дату и в другую сторону, чтобы вы могли быстро захватить определенный момент времени, а не возвращать результаты до тех пор, пока не найдете нужную временную метку. Часть идентификатора после подчеркивания '_' должна быть обрезана, так как это относится, в некотором роде, к пользователю IIRC. В примере есть четыре функции, которые, я надеюсь, помогут вам.

Счастливый взлом!

//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;*/ 
+0

Это выглядит потрясающе! Я тестирую его прямо сейчас - можете ли вы объяснить эти магические числа: 'return Math.round ((n * 0.008388608 - 11024476.5839159095) * 1000000000000);'? –

+0

Протестировано, ничего себе, работает по мере необходимости !!! Ты жжешь! :) –

+0

Ссылка на то, где вы нашли, как Instagram кодирует идентификаторы, будет полезна. Это пахнет незарегистрированной функциональностью. – FuriousFolder

2

Для поддержки this отличный ответ, Instagram ID генерируется с помощью функции plpgSQL:

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

Смежные вопросы