Instagram API-如何检索用户在 Instagram 上关注的人的列表

我想知道如何检索用户在 Instagram 上关注的人的名单。这是因为这个特定的用户是我关注的人。所以我能看到他/她的照片还有他在 Instagram 上的粉丝。

我如何使用 Instagram API 来做到这一点? 这样做合法吗?

215992 次浏览

You can use the following Instagram API Endpoint to get a list of people a user is following.

https://api.instagram.com/v1/users/{user-id}/follows?access_token=ACCESS-TOKEN

Here's the complete documentation for that endpoint. GET /users/user-id/follows

And here's a sample response from executing that endpoint. enter image description here

Since this endpoint required a user-id (and not user-name), depending on how you've written your API client, you might have to make a call to the /users/search endpoint with a username, and then get the user-id from the response and pass it on to the above /users/user-id/follows endpoint to get the list of followers.

IANAL, but considering it's documented in their API, and looking at the terms of use, I don't see how this wouldn't be legal to do.

Shiva's answer doesn't apply anymore. The API call "/users/{user-id}/follows" is not supported by Instagram for some time (it was disabled in 2016).

For a while you were able to get only your own followers/followings with "/users/self/follows" endpoint, but Instagram disabled that feature in April 2018 (with the Cambridge Analytica issue). You can read about it here.

As far as I know (at this moment) there isn't a service available (official or unofficial) where you can get the followers/followings of a user (even your own).

You can use Phantombuster. Instagram has set some rate limit, so you will have to use either multiple accounts or wait for 15 minutes for the next run.

The REST API of Instagram has been discontinued. But you can use GraphQL to get the desired data. Here you can find an overview: https://developers.facebook.com/docs/instagram-api

I've been working on some Instagram extension for chrome last few days and I got this to workout:

First, you need to know that this can work if the user profile is public or you are logged in and you are following that user.

I am not sure why does it work like this, but probably some cookies are set when you log in that are checked on the backend while fetching private profiles.

Now I will share with you an ajax example but you can find other ones that suit you better if you are not using jquery.

Also, you can notice that we have two query_hash values for followers and followings and for other queries different ones.

let config = {
followers: {
hash: 'c76146de99bb02f6415203be841dd25a',
path: 'edge_followed_by'
},
followings: {
hash: 'd04b0a864b4b54837c0d870b0e77e076',
path: 'edge_follow'
}
};

The user ID you can get from https://www.instagram.com/user_name/?__a=1 as response.graphql.user.id

After is just response from first part of users that u are getting since the limit is 50 users per request:

let after = response.data.user[list].page_info.end_cursor


let data = {followers: [], followings: []};


function getFollows (user, list = 'followers', after = null) {
$.get(`https://www.instagram.com/graphql/query/?query_hash=${config[list].hash}&variables=${encodeURIComponent(JSON.stringify({
"id": user.id,
"include_reel": true,
"fetch_mutual": true,
"first": 50,
"after": after
}))}`, function (response) {
data[list].push(...response.data.user[config[list].path].edges);
if (response.data.user[config[list].path].page_info.has_next_page) {
setTimeout(function () {
getFollows(user, list, response.data.user[config[list].path].page_info.end_cursor);
}, 1000);
} else if (list === 'followers') {
getFollows(user, 'followings');
} else {
alert('DONE!');
console.log(followers);
console.log(followings);
}
});
}

You could probably use this off instagram website but I did not try, you would probably need some headers to match those from instagram page.

And if you need for those headers some additional data you could maybe find that within window._sharedData JSON that comes from backend with csrf token etc.

You can catch this by using:

let $script = JSON.parse(document.body.innerHTML.match(/<script type="text\/javascript">window\._sharedData = (.*)<\/script>/)[1].slice(0, -1));

Thats all from me!

Hope it helps you out!

Here's a way to get the list of people a user is following with just a browser and some copy-paste (A pure javascript solution based on Deep Seeker's answer):

  1. Get the user's id (In a browser, navigate to https://www.instagram.com/user_name/?__a=1 and look for response -> graphql -> user -> id [from Deep Seeker's answer])

  2. Open another browser window

  3. Open the browser console and paste this in it

    options = {
    userId: your_user_id,
    list: 1 //1 for following, 2 for followers
    }

  4. change to your user id and hit enter

  5. paste this in the console and hit enter

    `https://www.instagram.com/graphql/query/?query_hash=c76146de99bb02f6415203be841dd25a&variables=` + encodeURIComponent(JSON.stringify({
    "id": options.userId,
    "include_reel": true,
    "fetch_mutual": true,
    "first": 50
    }))

  6. Navigate to the outputted link

(This sets up the headers for the http request. If you try to run the script on a page where this isn't open, it won't work.)

  1. In the console for the page you just opened, paste this and hit enter
    let config = {
    followers: {
    hash: 'c76146de99bb02f6415203be841dd25a',
    path: 'edge_followed_by'
    },
    following: {
    hash: 'd04b0a864b4b54837c0d870b0e77e076',
    path: 'edge_follow'
    }
    };
    
    
    var allUsers = [];
    
    
    function getUsernames(data) {
    var userBatch = data.map(element => element.node.username);
    allUsers.push(...userBatch);
    }
    
    
    async function makeNextRequest(nextCurser, listConfig) {
    var params = {
    "id": options.userId,
    "include_reel": true,
    "fetch_mutual": true,
    "first": 50
    };
    if (nextCurser) {
    params.after = nextCurser;
    }
    var requestUrl = `https://www.instagram.com/graphql/query/?query_hash=` + listConfig.hash + `&variables=` + encodeURIComponent(JSON.stringify(params));
    
    
    var xhr = new XMLHttpRequest();
    xhr.onload = function(e) {
    var res = JSON.parse(xhr.response);
    
    
    var userData = res.data.user[listConfig.path].edges;
    getUsernames(userData);
    
    
    var curser = "";
    try {
    curser = res.data.user[listConfig.path].page_info.end_cursor;
    } catch {
    
    
    }
    var users = [];
    if (curser) {
    makeNextRequest(curser, listConfig);
    } else {
    var printString =""
    allUsers.forEach(item => printString = printString + item + "\n");
    console.log(printString);
    }
    }
    
    
    xhr.open("GET", requestUrl);
    xhr.send();
    }
    
    
    if (options.list === 1) {
    
    
    console.log('following');
    makeNextRequest("", config.following);
    } else if (options.list === 2) {
    
    
    console.log('followers');
    makeNextRequest("", config.followers);
    }

After a few seconds it should output the list of users your user is following.

Edit 3/12/2021

Troubleshooting

If you are getting an unfulfilled promise, double check these things

  • Make sure you are logged in to Instagram (user12857969's answer)
  • Make sure you are not in incognito mode or otherwise preventing Instagram from verifying your login information.
  • Make sure the account whose information you are trying to access is either public, or they have allowed you to follow them.

One way to check for an issue is the make sure the page you navigate to in step 6 has data. If it looks like the following, then you are either not logged in, the user is private and you do not have access to view their follows/followers, or your browser is not allowing cookies and Instagram cannot confirm your identity:

{"data":{"user":{"edge_followed_by":{"count":196,"page_info":{"has_next_page":false,"end_cursor":null},"edges":[]},"edge_mutual_followed_by":{"count":0,"edges":[]}}},"status":"ok"}

I made my own way based on Caitlin Morris's answer for fetching all folowers and followings on Instagram. Just copy this code, paste in browser console and wait for a few seconds.

You need to use browser console from instagram.com tab to make it works.

let username = 'USERNAME'
let followers = [], followings = []
try {
let res = await fetch(`https://www.instagram.com/${username}/?__a=1`)


res = await res.json()
let userId = res.graphql.user.id


let after = null, has_next = true
while (has_next) {
await fetch(`https://www.instagram.com/graphql/query/?query_hash=c76146de99bb02f6415203be841dd25a&variables=` + encodeURIComponent(JSON.stringify({
id: userId,
include_reel: true,
fetch_mutual: true,
first: 50,
after: after
}))).then(res => res.json()).then(res => {
has_next = res.data.user.edge_followed_by.page_info.has_next_page
after = res.data.user.edge_followed_by.page_info.end_cursor
followers = followers.concat(res.data.user.edge_followed_by.edges.map(({node}) => {
return {
username: node.username,
full_name: node.full_name
}
}))
})
}
console.log('Followers', followers)


has_next = true
after = null
while (has_next) {
await fetch(`https://www.instagram.com/graphql/query/?query_hash=d04b0a864b4b54837c0d870b0e77e076&variables=` + encodeURIComponent(JSON.stringify({
id: userId,
include_reel: true,
fetch_mutual: true,
first: 50,
after: after
}))).then(res => res.json()).then(res => {
has_next = res.data.user.edge_follow.page_info.has_next_page
after = res.data.user.edge_follow.page_info.end_cursor
followings = followings.concat(res.data.user.edge_follow.edges.map(({node}) => {
return {
username: node.username,
full_name: node.full_name
}
}))
})
}
console.log('Followings', followings)
} catch (err) {
console.log('Invalid username')
}

There is another way of doing this. Instapy provides us set of API for doing this.

Here is a simple code that can be used for this. We need to pass the amount of followers we need, in case we need all the followers list we need to pass full as the parameter value for the amount. The file containing the list will be stored locally.

Just make a simple pip install command.

pip install instapy

Sample Code

from instapy import InstaPy


user = <Username>
password = <password>
gecko_path = <geckodriver path>
#instapy uses this internally
session = InstaPy(username=user, password=password,geckodriver_path= gecko_path)
session.login()
followers = session.grab_followers(username=user,amount=40)
print(followers)
following = session.grab_following(username=user,amount=40)
print(following)
session.end()

Link to its documentation: https://instapy.org/

https://i.instagram.com/api/v1/friendships/2/following/

Where 2 is the user ID of interest. It returns a json of a list of user IDs, usernames, full names, profile pic URLs etc. It takes a GET parameter ?count=n to limit the response.

If you need to get IG followers the best way in my oppinion is to login into IG on the web, and then take x-ig-app-id and cookie from request and then send GET Request to this endpoint: https://i.instagram.com/api/v1/friendships/{userId}/following/?count=20&max_id=12

    {
"users": [
{
"pk": 7385793727,
"username": "nebitno",
"full_name": "lela",
"is_private": true,
"profile_pic_url": "https://scontent-sof1-2.cdninstagram.com/v/t51.2885-19/s150x150/144485752_4993231520748255_75575875121006268732_n.jpg?cb=9ad74b5e-c1c39920&_nc_ht=scontent-sof1-2.cdninstagram.com&_nc_cat=103&_nc_ohc=956dXauIBogAX_zfWPW&edm=ALB854YBAAAA&ccb=7-4&oh=00_AT_EGZmL2bx-zMSBQqxYKUjIaYWVVyBnPH9__Y9jAccF0w&oe=61DFADB1&_nc_sid=04cb80",
"profile_pic_id": "2500168216063422867_7385792727",
"is_verified": false,
"follow_friction_type": 0,
"has_anonymous_profile_picture": false,
"has_highlight_reels": false,
"account_badges": [],
"latest_reel_media": 1641496960,
"is_favorite": false
},
...
]}

Further developed version of https://stackoverflow.com/a/63056537/11865501

  1. Open Instagram on your browser;
  2. Login to Instagram;
  3. Open your browser's console (CTRL + SHIFT + J);
  4. Paste the code below;
  5. Update the username in the first line;
  6. RUN IT (Hit enter)
const username = "USER_NAME_HERE";


/**
* Initialized like this so typescript can infer the type
*/
let followers = [{ username: "", full_name: "" }];
let followings = [{ username: "", full_name: "" }];
let dontFollowMeBack = [{ username: "", full_name: "" }];
let iDontFollowBack = [{ username: "", full_name: "" }];


followers = [];
followings = [];
dontFollowMeBack = [];
iDontFollowBack = [];


(async () => {
try {
console.log(`Process started! Give it a couple of seconds`);


const userQueryRes = await fetch(
`https://www.instagram.com/web/search/topsearch/?query=${username}`
);


const userQueryJson = await userQueryRes.json();


const userId = userQueryJson.users[0].user.pk;


let after = null;
let has_next = true;


while (has_next) {
await fetch(
`https://www.instagram.com/graphql/query/?query_hash=c76146de99bb02f6415203be841dd25a&variables=` +
encodeURIComponent(
JSON.stringify({
id: userId,
include_reel: true,
fetch_mutual: true,
first: 50,
after: after,
})
)
)
.then((res) => res.json())
.then((res) => {
has_next = res.data.user.edge_followed_by.page_info.has_next_page;
after = res.data.user.edge_followed_by.page_info.end_cursor;
followers = followers.concat(
res.data.user.edge_followed_by.edges.map(({ node }) => {
return {
username: node.username,
full_name: node.full_name,
};
})
);
});
}


console.log({ followers });


after = null;
has_next = true;


while (has_next) {
await fetch(
`https://www.instagram.com/graphql/query/?query_hash=d04b0a864b4b54837c0d870b0e77e076&variables=` +
encodeURIComponent(
JSON.stringify({
id: userId,
include_reel: true,
fetch_mutual: true,
first: 50,
after: after,
})
)
)
.then((res) => res.json())
.then((res) => {
has_next = res.data.user.edge_follow.page_info.has_next_page;
after = res.data.user.edge_follow.page_info.end_cursor;
followings = followings.concat(
res.data.user.edge_follow.edges.map(({ node }) => {
return {
username: node.username,
full_name: node.full_name,
};
})
);
});
}


console.log({ followings });


dontFollowMeBack = followings.filter((following) => {
return !followers.find(
(follower) => follower.username === following.username
);
});


console.log({ dontFollowMeBack });


iDontFollowBack = followers.filter((follower) => {
return !followings.find(
(following) => following.username === follower.username
);
});


console.log({ iDontFollowBack });


console.log(
`Process is done: Type 'copy(followers)' or 'copy(followings)' or 'copy(dontFollowBack)' in the console and paste it into a text editor to take a look at it'`
);
} catch (err) {
console.log({ err });
}
})();

As per @Jackov GI answer if you log into the web version go to your profile and click 'following' you can see the URL api used. From the F12 debug window grab the Request headers value for cookie and x-ig-app-id. Then you can fire a REST call get the results without hitting token server. The same mechanism can be used for the other API's To fully automate you might want to consider some other tool for loading the browser programatically and get your cookie.

One thing I did observe is that the user Id that comes back from my long token in FB setup seems to differ to my user id via the web. However using the user Id from the web the folloing code works for me. Tweek the params for differnt count items ect.

When you copy the cookie value remember to escape the quotes and back slashes.

Also this is super rough code lifted straight as I was testing not for code review!

var myfollowers = GetFollowers(<webuserid>).Result;


public async Task<InstragramUserNode> GetFollowers(long userId)
{
var getUserUrl = $"https://i.instagram.com/api/v1/friendships/{userId}/followers/?count=12&search_surface=follow_list_page";
    

using(var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.instagram.com/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("authority","i.instagram.com");


client.DefaultRequestHeaders.Add("path","/api/v1/friendships/{userId}/followers/?count=12&search_surface=follow_list_page");


client.DefaultRequestHeaders.Add("cookie","<your value>");
client.DefaultRequestHeaders.Add("x-ig-app-id","<yourvalue>");
      

var ff = await StreamWithNewtonsoftJson<Followers>(getUserUrl, client);
}


return new InstragramUserNode();
}


private static async Task<T> StreamWithNewtonsoftJson<T>(string uri, HttpClient httpClient)
{
using var httpResponse = await httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);


httpResponse.EnsureSuccessStatusCode(); // throws if not 200-299


if (httpResponse.Content != null && httpResponse.Content.Headers.ContentType.MediaType == "application/json")
{
var contentStream = await httpResponse.Content.ReadAsStreamAsync();


using var streamReader = new StreamReader(contentStream);
using var jsonReader = new JsonTextReader(streamReader);


var serializer = new JsonSerializer();


        

try
{
return serializer.Deserialize<T>(jsonReader);
}
catch(JsonReaderException)
{
Console.WriteLine("Invalid JSON.");
}
}
else
{
Console.WriteLine("HTTP Response was invalid and cannot be deserialised.");
}


return default;
}


public class Followers
{
public List<User> users { get; set; }
public bool big_list { get; set; }
public int page_size { get; set; }
public string next_max_id { get; set; }
public bool has_more { get; set; }
public bool should_limit_list_of_followers { get; set; }
public string status { get; set; }




public class User
{
public string pk { get; set; }
public string username { get; set; }
public string full_name { get; set; }
public bool is_private { get; set; }
public string pk_id { get; set; }
public string profile_pic_url { get; set; }
public string profile_pic_id { get; set; }
public bool is_verified { get; set; }
public bool has_anonymous_profile_picture { get; set; }
public bool has_highlight_reels { get; set; }
public List<object> account_badges { get; set; }
public int latest_reel_media { get; set; }
public bool is_favorite { get; set; }
}
}