所以,我正在尝试与某位追随者的朋友们。不必递归地挖掘,只需一个级别即可。
我能够将追随者拉得很好(看起来它可以处理超过75,000个追随者,所以我有90%的把握确定了那里的速率限制)。
但是我返回朋友的代码在返回15个关注者朋友之后抛出了身份验证错误。
换句话说,在这段代码中:
for (var i = 0; i < followerList.Count; i++)
{
await followersFriends(followerList[i]);
}
i == 15
时出现此错误:
LinqToTwitter.TwitterQueryException HResult = 0x80131500 Message = {“ request”:“ / 1.1 / friends / ids.json”,“ error”:“未授权。”}-请访问LINQ to Twitter FAQ(在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仅是为了澄清,该代码称为followersFriends。是的,我知道,我没有更改按钮名称= 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]);
}
}
答案 0 :(得分:0)
如您的笔记中所述,遇到TwitterQueryException
帐户时,会抛出一条带有“未授权”消息的1963joeym
。检查此帐户,我可以看到他们已经保护了它。 “受保护”的概念意味着除非该人“授权”您的帐户,否则任何人都无法看到该人的帐户或相关活动。由于他们尚未授权尝试查询其朋友列表的帐户,因此您将从Twitter收到HTTP 401未经授权。因此,显示“未授权”消息的原因。
尽管用户实体具有bool
Protected
属性,但根据您的情况进行检查并不可行,因为您仅使用ID列表,而没有完整的{ {1}}个实例可用。在这种情况下,您唯一可以做的就是处理异常并从那里恢复。有两个地方可以处理此异常:(1)查询原始好友列表时,(2)查询好友的好友列表时,如下所示:
User
请注意,我在try子句中使用了when子句,专门针对401未经授权的情况,在下面重复:
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());
}
对于好友列表,这使您仅处理 catch (TwitterQueryException tqExUnauthorized) when (tqExUnauthorized.StatusCode == HttpStatusCode.Unauthorized)
{
Console.WriteLine("This user hasn't given your account permission to view their account.");
}
部分,仍然可以保护任何其他不符合该条件的Unauthorized
。对于朋友的朋友列表,您只需要处理TwitterQueryException
异常,并让查询继续对剩余的朋友进行迭代。