У instagram есть API, который устареет до конца 2018 года. Всех пересаживают на новую платформу — Instagram Graph API.
Регистрация приложения на этой платформе требует некоторых усилий. Среди прочих сумасшедших требований выделяется необходимость предоставить т.н. скринкаст (screencast). Вы должны записать ролик, показывающий как вы будете использовать данные, получаемые через Instagram API.
Потому мы пойдем другим путем.
Что требуется получить?
Нужно понимать, что мы хотим получить, и возможно ли это сделать каким то альтернативным путем. Я хочу импортировать последние картинки и тексты описания с требуемой страницы.
Снимать ролики, и выполнять прочие идиотские требования — на это тратить время не хочется.
Возможно ли получить данные без создания приложения и использования API?
Теоретически — да. Инстаграм не требует авторизации для просмотра данных.
Вся необходимая информация, при том даже в формате json присутствует в html коде каждой страницы instagram. Без каких либо трудностей можно получить 12 последних записей.
Этого достаточно чтобы организовать импорт данных с какой то страницы, постоянно обновляя базу публикаций, подгружая свежие из последних 12 на странице пользователя.
Шепотка кода и никакой магии
JSON в теле страницы, откуда я извлекаю данные, содержит гораздо больше информации, чем мне нужно. Вы можете сами исследовать, какие полезные вещи возможно извлечь от туда.
Я закодировал парсинг в виде класса, который собираюсь потом расширять другим функционалом.
Начнем с примера использования:
1 2 3 4 5 |
<?php $feed = new FeedReaper('https://www.instagram.com/russia/'); $items = $feed->fetch(); print_r($items); ?> |
Выведет массив из 12 элементов (покажу только пару):
Для каждой картинки импортировано 4 поля:
- id — идентификатор поста;
- title — описание картинки в instagram;
- src — url изображения, не факт, что постоянный, но точно подходит для скачивания;
- shortcode — то же что и id, но может быть использован для embed запроса данных.
Для запроса данных по shortcode я также сделал функцию, но каких либо новых интересных данных, которые и так можно дернуть из json на странице, она не поставляет.
FeedReaper, класс для импорта данных из Instagram
После инициализации класса, передав url страницы intagram:
1 |
$feed = new FeedReaper('https://www.instagram.com/russia/'); |
Вы получаете доступ к следующим функциям:
fetch — то, что уже было показано в примере, извлекаем список фоток с текстом и идентификаторами;
embed — дополнительная функция, позволяющая выдернуть данные через embed instagram api по шот-коду публикации. Здесь я возвращаю полностью всё, что предоставляется instagram.
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
<?php class FeedReaper { var $type; var $src; // конструктор класса принимает URL страницы пользователя. function __construct($source) { if (strpos($source, 'instagram.com/') !== false) { $this->type = 'instagram'; $this->src = $source; } else { throw new Exception('Invalid source: ' . $source); } } // извлекает данные в виде массива public function fetch() { $func = 'fetch_' . $this->type; return $this->{$func}(); } // извлекает данные только по указанной записи (по shortcode) public function embed($id) { $func = 'embed_' . $this->type; return $this->{$func}($id); } // реализация функций fetch и embed для instagram private function embed_instagram($id) { $contextOptions = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false ) ); $context = stream_context_set_default($contextOptions); $file = @file_get_contents( 'https://api.instagram.com/oembed/?url=http://instagr.am/p/' . urlencode($id), false, $context); if ($file) { return json_decode($file, true, 512, JSON_BIGINT_AS_STRING); } return false; } private function fetch_instagram() { $contextOptions = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false ) ); $context = stream_context_set_default($contextOptions); $file = file_get_contents( $this->src, false, $context); $pos1 = strpos($file, 'window._sharedData = {'); if ($pos1 !== false) { $pos1 += 21; $pos2 = strpos($file, ';', $pos1); if ($pos2 !== false) { $data = json_decode( substr($file, $pos1, $pos2 - $pos1), true, 512, JSON_BIGINT_AS_STRING); if (!empty($data['entry_data']['ProfilePage'][0]['graphql']['user']['edge_owner_to_timeline_media']['edges'])) { $edges = $data['entry_data']['ProfilePage'][0]['graphql']['user']['edge_owner_to_timeline_media']['edges']; $items = array(); foreach ($edges as $edge) { $items[] = array( 'id' => $edge['node']['id'], 'title' => $edge['node']['edge_media_to_caption']['edges'][0]['node']['text'], 'src' => $edge['node']['display_url'], 'shortcode' => $edge['node']['shortcode'] ); } return $items; } } } return false; } } |
Что еще можно сделать?
Так мы получили только первую страницу с картинками (всего 12 штук). Теоретически возможно получить и следующие страницы.
Они догружаются через запросы вида /graphql/query/,
где используются следующие параметры:
Значения Айди, что используется для variables можно получить из кода страницы. А вот источник, время жизни и назначение query_hash — не ясно. Он одинаков для разных страниц.
В ответе на /graphql/query/ приходит аналогичный по структуре json, что мы извлекали из html кода.
Добрый день
можете уточнить что нужно настроить в аккаунте инстаграма чтобы получить данные?
пытаюсь получить данные из аккаунта https://www.instagram.com/bufet_taburet/ возвращает false
Спасибо.
В самом акке ничего не надо настраивать, достаточно того, что доступ к нему не ограничен.