ramtinak / InstagramApiSharp

A complete Private Instagram API for .NET (C#, VB.NET).
MIT License
792 stars 239 forks source link

MaxPagesToLoad(1) return thousands of followers on GetUserFollowersAsync #229

Closed houcz closed 5 years ago

houcz commented 5 years ago

I've:

Issue category

Language

Usage

Operating System

Describe your issue

When i call

result = await Helper.InstaApi.UserProcessor.GetUserFollowersAsync(_concurentUser.UserName, PaginationParameters.MaxPagesToLoad(1));

NextMaxId is null and GetUserFollowersAsync returns thousands of followers not only one page.

A few days ago, this working normally

ramtinak commented 5 years ago

Which version of InstagramApiSharp you are using it?

Maybe the desire username is a private user?!. Please give us the username you are trying to get followers list.

houcz commented 5 years ago

i use 1.3.5. version of InstagramApiSharp. username for example "czechoslovak_models" return 7236 followers thousands of followers returns all of usernames whitch i tested. it is hapens with PaginationParameters.MaxPagesToLoad(1).StartFromMaxId(_StartFromMaxId) and PaginationParameters.MaxPagesToLoad(1) too (see screenshot).

Skica32

ramtinak commented 5 years ago

I suggest you for requests like this, always use GetUserFollowersByIdAsync and GetUserFollowingByIdAsync. because it's divide your requests! Check this: https://github.com/ramtinak/InstagramApiSharp/issues/150

Also you don't need put if for this requests!

var result = await InstaApi.UserProcessor
    .GetUserFollowersByIdAsync(userIdPK, PaginationParameters.MaxPagesToLoad(1).StartFromMaxId(latestMaxId));

if MaxId was null or empty, it will get it from the beginning.

Good luck.

houcz commented 5 years ago

i dont undestand what you mean ...devide your requests? I create simple procedure from your example #150 but only for one call, because i want only one page, not all followers. As you see in screen still return 7416 Followers and NextMaxId is null.

zdrojak1

ramtinak commented 5 years ago

I didn't said use pagination parameters! I said use GetUserFollowersByIdAsync and GetUserFollowingByIdAsync.

You should get user id (pk) one time and store it (like storing max id) and then pass it to above functions.

Results for "czechoslovak_models" (10k followers): image

Here is my testing code:

        InstaUserShortList List = new InstaUserShortList();

        private long UserId = -1;
        private string LatestMaxId = "";
        private async Task<bool> GetFollowers(string username)
        {
            if(UserId == -1)
            {
                // get user id (pk)
                var user = await InstaApi.UserProcessor.GetUserAsync(username);
                if (!user.Succeeded)
                    return false;
                // store user id in some place
                UserId = user.Value.Pk;
            }

            var followers = await InstaApi.UserProcessor
                .GetUserFollowersByIdAsync(UserId, PaginationParameters.MaxPagesToLoad(1).StartFromMaxId(LatestMaxId));

            LatestMaxId = followers.Value.NextMaxId;
            if (followers.Succeeded)
            {
                List.AddRange(followers.Value);
                return true;
            }
            else
                return false;

        }

and for running above code:

            do
            {

               var flag = await GetFollowers("czechoslovak_models");

            } while (LatestMaxId != null);

And about dividing requests: For normal behavior of GetUserFollowersAsync or GetUserFollowingsAsync pagination with setting PaginationParameters.Empty everything is OK and it will get all pages(sometimes you may have issue with this, so many people don't like to use Empty property).

But everything is OK with PaginationParameters.Empty and it's not OK when use getting pages one by one by calling GetUserFollowersAsync or GetUserFollowingsAsync, why ?!

When you pass a username to GetUserFollowersAsync or GetUserFollowingsAsync, API requires user id(pk) not username so InstagramApiSharp will call GetUserAsync function automatically to get user id(pk) from the Instagram. and after that user id arrived, it start to getting the followers/followings.

When you use PaginationParameters.Empty, since you need to call GetUserFollowersAsync or GetUserFollowingsAsync one time, so InstagramApiSharp will call GetUserAsync one time. and everything works fine.

But in your scenario or #150, you call GetUserFollowersAsync or GetUserFollowingsAsync over and over, For single calling GetUserFollowersAsync or GetUserFollowingsAsync functions, InstagramApiSharp will send 2 requests to the Instagram.

Imaging 50 pages is available and you keep calling GetUserFollowersAsync or GetUserFollowingsAsync: Results: 50 * 2 = 100 requests, and instagram will deny your requests in some place. To preventing calling GetUserAsync everytime, we created GetUserFollowersByIdAsync and GetUserFollowingByIdAsync functions which never calls GetUserAsync, and you need to pass user id(pk) exchange of username.

and for 50 pages, only requests 50 times (divide your requests!~!)

I hope you understand my point.

A quick todo that I wrote in #150:

var user = await InstaApi.UserProcessor.GetUserAsync("desire username");

var followers = await InstaApi.UserProcessor
                .GetUserFollowersByIdAsync(user.Value.Pk, PaginationParameters.MaxPagesToLoad(1));

var followings = await InstaApi.UserProcessor
                .GetUserFollowingByIdAsync(user.Value.Pk, PaginationParameters.MaxPagesToLoad(1));

Good luck.

houcz commented 5 years ago

OK. Thats clear why using GetUserFollowersByIdAsync is better then by UserName. But i dont want 10 000 follower per call this function. I think that PaginationParameters.MaxPagesToLoad(1) return only one page (100-200 followers) and returns StartFromMaxId for next page. I want call pages one by one, because i display this data on the screen and for my application is this better then saving thausands acconts and then making some paggination of this data. I have my application almost half year and this did work ok. Until now.

ramtinak commented 5 years ago

As I said before, only PaginationParameters.Empty will read all pages, for MaxPagesToLoad will gets the requested pages.

As you can see, I used do while loop to show all, and it's one by one you can do this by yourself.

houcz commented 5 years ago

OK. Than again. As you can see i used only ONE!! call of method with PaginationParameters.MaxPagesToLoad(1) and i get 7416 followers! And that is the problem! zdrojak1

ramtinak commented 5 years ago

Post your debug logs here.

houcz commented 5 years ago

Problem solved. This was some issue on Instagram. Only for my acconut. Today is everythink ok and MaxPageToLoad returns about 150-200 followers.