简体   繁体   中英

How to get all images of hashtag in Instagram without API?

This is the code that I used to get images of hashtag without API. I do not want to use any credentials. It does not require me to add either client_id or access token. But I only get 15 images. How can I get all the images?

 <div>

    <form action='#' method='post'>
    <input type='input' name='txttag' />
    <input type='submit' value='Get Image' />
    </form>

    </div>


    <?php 
    function scrape_insta_hash($tag) {
        $insta_source = file_get_contents('https://www.instagram.com/explore/tags/'.$tag.'/'); // instagrame tag url
        $shards = explode('window._sharedData = ', $insta_source);
        $insta_json = explode(';</script>', $shards[1]); 
        $insta_array = json_decode($insta_json[0], TRUE);
        return $insta_array; // this return a lot things print it and see what else you need
    }

    if(isset($_POST['txttag']))
    {
        $tag =$_POST['txttag']; // tag for which ou want images 
        $results_array = scrape_insta_hash($tag);
        $limit = 15; // provide the limit thats important because one page only give some images then load more have to be clicked
        $image_array= array(); // array to store images.
            for ($i=0; $i < $limit; $i++) { 
                $latest_array = $results_array['entry_data']['TagPage'][0]['tag']['media']['nodes'][$i];
                $image_data  = '<img src="'.$latest_array['thumbnail_src'].'">'; // thumbnail and same sizes 
                //$image_data  = '<img src="'.$latest_array['display_src'].'">'; actual image and different sizes 
                array_push($image_array, $image_data);
            }
            foreach ($image_array as $image) {
                echo $image;// this will echo the images wrap it in div or ul li what ever html structure 
            }
            //https://www.instagram.com/explore/tags/your-tag-name/
    }
    ?>



    <style>
    img {
      height: 200px;
      margin: 10px;
    }
    </style>

Easily way is request with ?__a=1 like https://www.instagram.com/explore/tags/girls/?__a=1 and receive JSON without parsing HTML and window._sharedData =

In json you can see page_info scope with end_cursor :

"page_info": {
    "has_previous_page": false,
    "start_cursor": "1381007800712523480",
    "end_cursor": "J0HWCVx1AAAAF0HWCVxxQAAAFiYA",
    "has_next_page": true
},

use end_cursor to request next portion of images:

https://www.instagram.com/explore/tags/girls/?__a=1&max_id=J0HWCVx1AAAAF0HWCVxxQAAAFiYA

UPD:

<?php

$baseUrl = 'https://www.instagram.com/explore/tags/girls/?__a=1';
$url = $baseUrl;

while(1) {
    $json = json_decode(file_get_contents($url));
    print_r($json->tag->media->nodes);
    if(!$json->tag->media->page_info->has_next_page) break;
    $url = $baseUrl.'&max_id='.$json->tag->media->page_info->end_cursor;
}

The Answer from Legionar was great but it is not working anymore. I had to update the code in my working Environment here is how it works for me:

function scrape_insta_hash($tag) {
  $insta_source = file_get_contents('https://www.instagram.com/explore/tags/'.$tag.'/'); // instagrame tag url
  $shards = explode('window._sharedData = ', $insta_source);
  $insta_json = explode(';</script>', $shards[1]);
  $insta_array = json_decode($insta_json[0], TRUE);
  return $insta_array; // this return a lot things print it and see what else you need
}

$tag = "my_hashtag";
$results_array = scrape_insta_hash($tag);

$limit = 18; // provide the limit thats important because one page only give some images then load more have to be clicked

for ($i=$limit; $i >= 0; $i--) {
  if(array_key_exists($i,$results_array['entry_data']['TagPage'][0]["graphql"]["hashtag"]["edge_hashtag_to_media"]["edges"])){
    $latest_array = $results_array['entry_data']['TagPage'][0]["graphql"]["hashtag"]["edge_hashtag_to_media"]["edges"][$i]["node"];

      $newPosting = [
        "image"=>$latest_array['display_url'],
        "thumbnail"=>$latest_array['thumbnail_src'],
        "instagram_id"=>$latest_array['id'],
        "caption"=>$latest_array['caption']['edge_media_to_caption']['edges'][0]["node"]["text"],
        "link"=>"https://www.instagram.com/p/".$latest_array['shortcode'],
        "date"=>$latest_array['taken_at_timestamp']
      ];

      echo "<pre>"; 
      print_r($newPosting); 
      echo "/<pre>"; 

  }
}

You may need to change the "newPosting" array depending on what you need but at least for now you can get the instagram data with this method. Also there is more data inside $latest_array . Different image-sizes, comments and likes for example.

This one works for me perfectly.

I only needed the thumbnails. You can easily change it to full size image. This example does not solve pagination, but you can do that from @ilyapt answer.

$tag = 'coronavirus';
$json = json_decode(file_get_contents("https://www.instagram.com/explore/tags/$tag/?__a=1", true));

$i = 0;
foreach($json->graphql->hashtag->edge_hashtag_to_media->edges as $key => $value) {
    $img = $value->node->thumbnail_resources[0]->src;
    echo "<img src='$img'>";
    if (++$i == 9) break; // limit to the 9 newest posts
}

@olaf answer worked great for me!

@Tomas The limit is the number of posts that will be returned by the function so that it doesn't return all of them.

Also: this function puts the Instagram posts in order from oldest to newest. If you want the latest to be first and go backwards to the limit number:

Change

for ($i=$limit; $i >= 0; $i--)

to

for ($i=0; $i < $limit; $i++)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM