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 acces
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
}
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.
@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++)
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;
}