C # - список друзей - попадание аутентификации сбой в середине процесса - PullRequest
0 голосов
/ 01 июля 2018

Итак, я стараюсь друзей всех чьих-то последователей. Не рекурсивно копать, только этот единственный уровень.

Я в состоянии вывести фолловеров очень хорошо (и, похоже, он может обрабатывать более 75 тыс. Фолловеров, поэтому я на 90% уверен, что у меня там хорошие ограничения по скорости).

Но мой код для извлечения друзей выдает ошибки аутентификации после того, как он возвращает 15 друзей последователей.

Другими словами, в этом фрагменте кода:

for (var i = 0; i < followerList.Count; i++)
{
  await followersFriends(followerList[i]);
}

Я получаю эту ошибку, когда i == 15:

LinqToTwitter.TwitterQueryException HResult = 0x80131500 Сообщение = {"запрос": "/ 1.1 / friends / ids.json", "ошибка": "Не авторизован."} - Пожалуйста, посетите FAQ по LINQ to Twitter (на HelpLink) для помощи в устранении этой ошибки.

Похоже, что он полностью получает 15 списков, это 16-й, который выбрасывает его. У меня такое ощущение, что это не совпадение, что это то же самое, что ограничение скорости, хотя странная ошибка, если это ограничение скорости.

Я брошу чек, чтобы посмотреть, кратны ли мы 15 и сделаем 15-минутную паузу, но если есть вероятность, что это не сработает, у кого-нибудь есть теория относительно того, что еще может быть здесь происходит?

ETA: я пытался повторить свою аутентификацию (на основе приложений) при каждом запуске через followersFriends. Не помогло.

ETA2:

Это новый телефонный код:

for (var i = 0; i < followerList.Count; i++)
{
  if (i % 15 == 0 && i != 0) {
    Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - i = " + i + " and user = " + followerList[i]);
    PauseThatRefreshes("friends");
    RunMe();
  }

  await followersFriends(followerList[i]);
}

А вот код, который называется:

private async Task followersFriends(ulong uid)
{
  var twitterCtx2 = new TwitterContext(m_foo);

  Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Start Friend Get for " + uid.ToString() + " ***");

  long cursor = -1;

  do
  {
    var friendList = await (from friend in twitterCtx2.Friendship where friend.Type == FriendshipType.FriendIDs && friend.UserID == uid.ToString() && friend.Cursor == cursor select friend).SingleOrDefaultAsync();

    if (twitterCtx2.RateLimitRemaining <= 2)
    {
      Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Pausing A ***");
      Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - Friends Rate Limit Remaining at Pause A: " +
        twitterCtx2.RateLimitRemaining.ToString());
      PauseThatRefreshes("friends");
    }

    if (friendList != null &&
      friendList.IDInfo != null &&
      friendList.IDInfo.IDs != null) {
      cursor = friendList.CursorMovement.Next;
      Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - Friends Rate Limit Remaining: " + twitterCtx2.RateLimitRemaining.ToString());
      friendList.IDInfo.IDs.ForEach(id => Output(uid.ToString(), id.ToString()));
    }

    if (twitterCtx2.RateLimitRemaining <= 2)
    {
      Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Pause B ***");
      Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - Friends Rate Limit Remaining at Pause B: " + twitterCtx2.RateLimitRemaining.ToString());
      PauseThatRefreshes("friends");
    }
  } while (cursor != 0);

  Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Stop Friend Get for " + uid.ToString() + " ***");
  Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - Friends Rate Limit Remaining at stop: " + twitterCtx2.RateLimitRemaining.ToString());

  return;
}

ETA только для пояснения, код, который вызывает последователей друзей. Да, я знаю, я не менял название кнопки = D. Это больше о сборе данных, и я предпочитаю форму, а не командную строку ... Я понятия не имею, почему. В любом случае, ни здесь, ни там:

        private async void button2_Click(object sender, EventArgs e)
    {

        var twitterCtx = new TwitterContext(m_foo);
        string[] header = { "Account,Follows" };
        File.WriteAllLines(@"C:\temp\followersFriends.txt", header);

        //List to store ids of followers of main account
        List<ulong> followerList = new List<ulong>();
        // get main accounts followers and put into an array
        long cursor = -1;
        Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Start Follower Get ***");
        do
        {

            var followers =
    await
    (from follower in twitterCtx.Friendship
     where follower.Type == FriendshipType.FollowerIDs &&
           follower.ScreenName == "[[redacted]]" && 
           follower.Cursor == cursor
     select follower)
    .SingleOrDefaultAsync();
            if (followers != null &&
                followers.IDInfo != null &&
                followers.IDInfo.IDs != null
                &&
                followers.CursorMovement != null)
            {
                cursor = followers.CursorMovement.Next;
                followers.IDInfo.IDs.ForEach(id =>
                  followerList.Add(id));
            }

            if (twitterCtx.RateLimitRemaining <= 2)
                PauseThatRefreshes("followers");
        } while (cursor != 0);
        Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Done Follower Get ***");

        for (var i = 0; i < followerList.Count; i++)
        {
            if (i % 15 == 0 && i != 0)
            {
                Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - i = " + i 
                    + " and user = " + followerList[i]);
                PauseThatRefreshes("friends");
                RunMe();
            }
            await followersFriends(followerList[i]);
        }
    }

1 Ответ

0 голосов
/ 02 июля 2018

Как указано в ваших заметках, при обнаружении учетной записи 1963joeym выдается сообщение TwitterQueryException с сообщением "Not Authorized". Проверяя эту учетную запись, я вижу, что они ее защитили. Понятие «защищенный» означает, что никто не может видеть учетную запись человека или связанную с ним деятельность, если этот человек не «авторизует» вашу учетную запись. Поскольку они не авторизовали учетную запись, которая пытается запросить их список друзей, вы получаете HTTP 401 Unauthorized, из Twitter. Таким образом, причина появления сообщения «Не авторизован».

Хотя сущности пользователя имеют свойство bool Protected, проверить это в вашем случае нецелесообразно, поскольку вы работаете только со списком идентификаторов и не имеете полного доступного экземпляра User. , В этой ситуации единственное, что вы можете сделать, это обработать исключение и восстановиться оттуда. Есть два способа обработки этого исключения: (1) при запросе исходного списка друзей и (2) при запросе списка друзей, показанного ниже:

        var allFollowerIds = new List<ulong>();
        Friendship followers = null;
        long cursor = -1;
        do
        {
            try
            {
                followers =
                    await
                    (from follower in twitterCtx.Friendship
                     where follower.Type == FriendshipType.FollowerIDs &&
                           follower.UserID == "1039951639" &&// "15411837" &&
                           follower.Cursor == cursor &&
                           follower.Count == 500
                     select follower)
                    .SingleOrDefaultAsync();
            }
            catch (TwitterQueryException tqExUnauthorized) when (tqExUnauthorized.StatusCode == HttpStatusCode.Unauthorized)
            {
                Console.WriteLine("This user hasn't given your account permission to view their account.");
            }
            catch (TwitterQueryException tqe)
            {
                Console.WriteLine(tqe.ToString());
                break;
            }

            if (followers != null &&
                followers.IDInfo != null &&
                followers.IDInfo.IDs != null)
            {
                cursor = followers.CursorMovement.Next;

                allFollowerIds.AddRange(followers.IDInfo.IDs);
            }

        } while (cursor != 0);

        cursor = -1;
        foreach (var uid in allFollowerIds)
        {
            Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Start Friend Get for " + uid.ToString() + " ***");

            do
            {
                Friendship friendList = null;
                try
                {
                    friendList = await (from friend in twitterCtx.Friendship where friend.Type == FriendshipType.FriendIDs && friend.UserID == uid.ToString() && friend.Cursor == cursor select friend).SingleOrDefaultAsync();
                }
                catch (TwitterQueryException tqExUnauthorized) when (tqExUnauthorized.StatusCode == HttpStatusCode.Unauthorized)
                {
                    Console.WriteLine("This user hasn't given your account permission to view their account.");
                }

                if (twitterCtx.RateLimitRemaining <= 2)
                {
                    Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Pausing A ***");
                    Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - Friends Rate Limit Remaining at Pause A: " +
                      twitterCtx.RateLimitRemaining.ToString());
                    //PauseThatRefreshes("friends");
                }

                if (friendList != null &&
                  friendList.IDInfo != null &&
                  friendList.IDInfo.IDs != null)
                {
                    cursor = friendList.CursorMovement.Next;
                    Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - Friends Rate Limit Remaining: " + twitterCtx.RateLimitRemaining.ToString());
                    //friendList.IDInfo.IDs.ForEach(id => Output(uid.ToString(), id.ToString()));
                }

                if (twitterCtx.RateLimitRemaining <= 2)
                {
                    Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Pause B ***");
                    Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - Friends Rate Limit Remaining at Pause B: " + twitterCtx.RateLimitRemaining.ToString());
                    //PauseThatRefreshes("friends");
                }
            } while (cursor != 0);

            Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - *** Stop Friend Get for " + uid.ToString() + " ***");
            Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + " - Friends Rate Limit Remaining at stop: " + twitterCtx.RateLimitRemaining.ToString());
        }

Обратите внимание, что я использовал try / catch с предложением when, специально для сценария 401 Unauthorized, который повторяется ниже:

        catch (TwitterQueryException tqExUnauthorized) when (tqExUnauthorized.StatusCode == HttpStatusCode.Unauthorized)
        {
            Console.WriteLine("This user hasn't given your account permission to view their account.");
        }

Для списка друзей это позволяет вам обрабатывать только часть Unauthorized и при этом защищать любые другие TwitterQueryException, которые не соответствуют этим критериям. Что касается списка друзей друга, вам нужно обработать только исключение Unauthorized и позволить запросу продолжать повторяться для оставшихся друзей.

...