Вывод фоток с Instagram по тегу или юзеру без токена

Всем привет!

Если у вас есть задача вывести фотографии по нику или тегу то можете использовать данное решение:

Сниппет instagram.php
<?php
// Тип вывода: все фото по хештегу или все фото из аккаунта
$type = (isset($type) && 'user' == $type)?'user':'tag';

function getPublicInfo($name, $type) {
    $url     = ('tag' == $type)?sprintf("https://www.instagram.com/explore/tags/$name"):sprintf("https://www.instagram.com/$name/");
    
    $content = file_get_contents($url);
    $content = explode("window._sharedData = ", $content)[1];
    $content = explode(";</script>", $content)[0];
    $data    = json_decode($content, true);
    $out     = ('tag' == $type)?$data['entry_data']['TagPage'][0]['graphql']['hashtag']['edge_hashtag_to_media']['edges']:$data['entry_data']['ProfilePage'][0]['graphql']['user']['edge_owner_to_timeline_media']['edges'];
    return $out;
}

$images = [];

$cacheFile['tag'] = MODX_CORE_PATH.'cache/insta.json';
$cacheFile['user'] = MODX_CORE_PATH.'cache/insta_user.json';

$cacheData = (file_exists($cacheFile[$type]))?json_decode(file_get_contents($cacheFile[$type]),1):array('time'=>0,'images'=>array());
if(!isset($cacheTime)){
    $cacheTime = 1800;
}
if(!isset($limit))
{
    $limit = 12;
}

$imageIndex = 0;

if($cacheData['time']+$cacheTime < time() ) {
    $profile = getPublicInfo($name, $type);
    foreach ($profile as $item){
        $images[$imageIndex] = [
            'image'=>$item['node']['display_url'],
            'shortcode'=>$item['node']['shortcode'],
            'thumb'=>$item['node']['thumbnail_src'],
            'thumb_150'=>$item['node']['thumbnail_src'],
            'thumb_240'=>$item['node']['thumbnail_src'],
            'thumb_320'=>$item['node']['thumbnail_src'],
            'thumb_480'=>$item['node']['thumbnail_src'],
            'thumb_640'=>$item['node']['thumbnail_src'],
        ];
        foreach ($item['node']['thumbnail_resources'] as $thumb)
        {
            $images[$imageIndex]['thumb_'.$thumb['config_width']] = $thumb['src'];
            $thumbs[$thumb['config_width']] = $thumb['src'];
        }
        
        $imageIndex++;
    }
    $cacheData['time'] = time();
    $cacheData['images'] = $images;
    file_put_contents($cacheFile[$type], json_encode($cacheData,256));
} else {
    $images = $cacheData['images'];
}
if($randomize){
    shuffle($images);
}
$modx->setPlaceholders(array('type'=>$type, 'name'=>$name));
return  array_slice($images, 0, $limit);

Для выбора тег или юзер и его ввода создам TV:


Вызов:
{set $instagram_name = $_modx->resource.instagram_name ?: 'ibochkarev'}
{set $instagram_type = $instagram_type ?: 'tag'}
{set $instagram_img_count = $_modx->resource.instagram_img_count ?: '3'}

{set $instagrammList = '@FILE snippets/instagram.php' | snippet : [
    'type' => $instagram_type,
    'name' => $instagram_name,
    'cacheTime' => 1800,
    'thumbSize' => 240,
    'limit' => $instagram_img_count,
    'randomize' => 1,
]}
Пример разметки:
<section class="about-gallary wrapper">
  <div class="about-gallary__wrapper">
    <div class="about-gallary__img-wrap">
      {foreach $instagrammList as $item}
        <a href="https://www.instagram.com/p/{$item.shortcode}" class="about-gallary__img" target="_blank">
          <picture>
              <source media="(max-width: 665px)" srcset="{$item.thumb_150}, {$item.thumb_150} 2x, {$item.thumb_320} 3x">
              <source media="(max-width: 2399px)" srcset="{$item.thumb_240}, {$item.thumb_480} 2x, {$item.thumb_640} 3x">
              <source media="(min-width: 2400px)" srcset="{$item.thumb_320}, {$item.thumb_640} 2x">
              <img src="{$item.thumb}">
          </picture>
        </a>
      {/foreach}
    </div>
    <a href="{'inst' | config}" class="about-gallary__btn btn center">{'btn_see_all' | lexicon}</a>
  </div>
  <div class="line"><span class="line__text">{'title_golden_art_instagram' | lexicon}</span></div>
</section>

Изначально автор сниппета @PG потом не много доработан.
Иван Бочкарев
14 апреля 2020, 17:52
modx.pro
17
898
+13
Поблагодарить автора Отправить деньги

Комментарии: 7

vectorserver
14 апреля 2020, 19:23
7
+11
Так проще и быстрее, без обид друг)
Код сниппета ParseInsta:
<?php
//ParseInsta
$cacheKey = "insta_".md5($url);

$returnCache = $modx->cacheManager->get("$cacheKey");

if(!$returnCache){
    $doc = new DOMDocument();
    $doc->loadHTMLFile($url);
    $xpath = new DOMXpath($doc);
    $sharedData = $xpath->query("//html/body/script[1]")->item(0)->textContent;
    $str = $sharedData;
    $modx->cacheManager->set($cacheKey, $str, 7200*60);
    return $str;
}

return $returnCache;
И далее JSON обрабатываем через JS или конвертуть в массив и использовать в чанках
<script>
var instaphotos = [[ParseInsta? $url=`https://www.instagram.com/explore/tags/кофесос`]];
//bla bla bla
</script>
    Саша Туманов
    20 апреля 2020, 22:05
    1
    +1
    Вот готовое к использованию для вывода ленты юзера:

    <?php
    $cacheKey = "insta_".md5($url);
    
    if (!$pdo = $modx->getService('pdoTools')) return false;
    $returnCache = $modx->cacheManager->get("$cacheKey");
    $data = '';
    
    if(!$returnCache) {
    	$doc = new DOMDocument();
    	libxml_use_internal_errors(true);
    	$doc->loadHTMLFile($url);
    	libxml_clear_errors();
    	$xpath = new DOMXpath($doc);
    	$sharedData = $xpath->query("//html/body/script[1]")->item(0)->textContent;
    	preg_match_all('/window\._sharedData = \{(.*)\};/ism', $sharedData, $matches);
    	if (!empty($matches[1][0])) {
    		$res = json_decode('{' . $matches[1][0] . '}', true);
    		
    		$media = array_slice($res['entry_data']['ProfilePage'][0]['graphql']['user']['edge_owner_to_timeline_media']['edges'], 0, $limit);
    		if (!empty($media)) {
    			foreach ($media as $row) {
    				$data .= $pdo->getChunk($tpl, array(
    					// 'image'     => $row['node']['display_url'],
    					'thumb'     => $row['node']['thumbnail_src'],
    					// 'thumb_150' => $row['node']['thumbnail_resources'][0]['src'],
    					'thumb_240' => $row['node']['thumbnail_resources'][1]['src']
    				));
    			}
    		}
    	}
    	$modx->cacheManager->set($cacheKey, $data, 7200*60);
    	return $data;
    }
    
    return $returnCache;

    И вызов:

    {$_modx->runSnippet("@FILE snippets/parseInsta.php", [
    	'url' => 'https://www.instagram.com/someuser/',
    	'limit' => 4,
    	'tpl' => '@INLINE <a href="{$thumb}" class="gallery__item"><img src="{$thumb_240}" alt=""></a>'
    ])}
      Олег
      05 мая 2020, 23:37
      0
      подскажите, можно ли вывести текст под фото, если да то как?
        iWatchYouFromAfar
        06 мая 2020, 01:37
        +1
        В параметре tpl оформляется вывод изображений, сверстайте его под себя и выводите что угодно.
        Bor
        Bor
        10 июля 2020, 17:15
        0
        Всем привет. А можно такое же для твиттера?
        Или, сколько бы это могло стоить?
          Андрей
          11 июля 2020, 03:24
          0
          У твиттера есть свой инструмент для встраивания ленты на сайт, в отличии от инстаграма. Или нужен именно парсинг со своим оформлением?
            Bor
            Bor
            11 июля 2020, 11:32
            0
            я пробовал. инструмент твиттера дает только возможность вывода:
            1) либо из своей сформированной коллекции tweetdeck.twitter.com/
            2) либо из конкретной группы.
            А чтобы выводит по произвольному хештегу, такого не видел. Видимо, через апи должно быть. А иногда хочется собрать упоминание о своем продукте на сайте.
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          7