如何使用游标在 Twitter API 中使用 c# 遍历 GET 关注者/列表的结果集? [英] How to use cursors to iterate through the result set of GET followers/list in Twitter API using c#?
问题描述
我一直在尝试一种方法,可以在 GET follower/list API 调用的结果集的下一页中获取数据.我可以使用前 20 个关注者的数据而不是其他人的数据获取默认数据集.要获取其他关注者的数据,我必须使用 next_cursor 访问下一页,但它不起作用.我尝试使用此链接中提到的伪代码.https://dev.twitter.com/docs/misc/cursoring
I have been trying a way to get the data in the next page of the result set of GET followers/list API call. I can get the default data set with the data of first 20 followers and not the others. To get the data of other followers i have to access the next page using the next_cursor but it's not working. I tried using the pseudo-code mentioned in this link. https://dev.twitter.com/docs/misc/cursoring
是否必须使用这个(开发站点中提到了这一点):
Is it a must to use this(this is mentioned in the dev. site):
var api-path = "https://api.twitter.com/1.1/endpoint.json?screen_name=targetUser"
因为我一直使用资源网址作为,
Because I have been using the resource URL as,
var resource_url = "https://api.twitter.com/1.1/followers/list.json";
并且我尝试将 next_cursor 附加到相同的资源 URL.
and I tried appending the next_cursor to the same resource URL.
var url_with_cursor = resource_url + "&cursor=" + 1463101490306580067;
然后创建请求.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url_with_cursor);
但是在获得响应时,我在这一行中遇到了异常.
but I'm getting an exception in this line when getting the response.
WebResponse response = request.GetResponse();
我得到的错误是
The Remote Server returned an Error 401 Unauthorized
有人能告诉我做游标的确切方法,或者在请求中包含游标的确切方法.我正在使用 asp.net C# 网络应用程序.
Can someone tell the exact way to do cursor-ing, or the exact way to include the cursor in the request. I'm using a asp.net C# web application.
这是我的代码,oauth_token、oauth_token_secret、oauth_consumer_key、oauth_consumer_secret、oauth_version 和 oauth_signature_method 在我的应用程序中定义
Here's my code, The oauth_token, oauth_token_secret, oauth_consumer_key, oauth_consumer_secret, oauth_version and oauth_signature_method are defined in my application
var resource_url = "https://api.twitter.com/1.1/followers/list.json";
var cursor = "-1";
do
{
var url_with_cursor = resource_url + "&cursor=" + cursor;
// unique request details
var oauth_nonce = Convert.ToBase64String(
new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
var timeSpan = DateTime.UtcNow
- new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
// create oauth signature
var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}";
var baseString = string.Format(baseFormat,
oauth_consumer_key,
oauth_nonce,
oauth_signature_method,
oauth_timestamp,
oauth_token,
oauth_version
//,Uri.EscapeDataString(status)
);
baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));
var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
"&", Uri.EscapeDataString(oauth_token_secret));
string oauth_signature;
using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
{
oauth_signature = Convert.ToBase64String(
hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
}
// create the request header
var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
"oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
"oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
"oauth_version=\"{6}\"";
var authHeader = string.Format(headerFormat,
Uri.EscapeDataString(oauth_nonce),
Uri.EscapeDataString(oauth_signature_method),
Uri.EscapeDataString(oauth_timestamp),
Uri.EscapeDataString(oauth_consumer_key),
Uri.EscapeDataString(oauth_token),
Uri.EscapeDataString(oauth_signature),
Uri.EscapeDataString(oauth_version)
);
// make the request
ServicePointManager.Expect100Continue = false;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url_with_cursor);
request.Headers.Add("Authorization", authHeader);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
WebResponse response = request.GetResponse();
string result = new StreamReader(response.GetResponseStream()).ReadToEnd();
JObject j = JObject.Parse(result);
JArray data = (JArray)j["users"];
cursor = (String)j["next_cursor_str"];
} while (!cursor.Equals("0"));
谢谢.
推荐答案
您应该通过授权请求进行不同的身份验证调用.一旦获得批准,您就可以使用光标调用 webresponse.请参阅下面的示例代码(特别注意 StartCreateCall 方法,在该方法中完成身份验证.然后通过 CallData 方法检索来自 Twitter 的数据):
you should make a different call to authenticate, by an authorization request. Once that has been granted, you can call the webresponse with the cursor. See my sample code below (Take special note to the StartCreateCall method, where the authentication is done. The data from Twitter is then retrieved by the CallData method):
public partial class twitter_followers : System.Web.UI.Page
{
public string strTwiterFollowers { get; set; }
private List<TwiterFollowers> listFollowers = new List<TwiterFollowers>();
private string screen_name = string.Empty;
// oauth application keys
private string oauth_consumer_key = string.Empty;
private string oauth_consumer_secret = string.Empty;
// oauth implementation details
private string resource_urlFormat = "https://api.twitter.com/1.1/followers/list.json?screen_name={0}&cursor={1}";
// unique request details
private string oauth_nonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
protected void Page_Load(object sender, EventArgs e)
{
//just get your request parameters from the config file.
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings[GetVariableName(() => screen_name)])) {
screen_name = ConfigurationManager.AppSettings[GetVariableName(() => screen_name)];
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings[GetVariableName(() => oauth_consumer_key)]))
{
oauth_consumer_key = ConfigurationManager.AppSettings[GetVariableName(() => oauth_consumer_key)];
}
if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings[GetVariableName(() => oauth_consumer_secret)]))
{
oauth_consumer_secret = ConfigurationManager.AppSettings[GetVariableName(() => oauth_consumer_secret)];
}
StartCreateCall();
}
// Do the authenticate by an authorization request
private void StartCreateCall() {
// You need to set your own keys and screen name
var oAuthUrl = "https://api.twitter.com/oauth2/token";
// Do the Authenticate
var authHeaderFormat = "Basic {0}";
var authHeader = string.Format(authHeaderFormat,
Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(oauth_consumer_key) + ":" +
Uri.EscapeDataString((oauth_consumer_secret)))
));
var postBody = "grant_type=client_credentials";
HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(oAuthUrl);
authRequest.Headers.Add("Authorization", authHeader);
authRequest.Method = "POST";
authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (Stream stream = authRequest.GetRequestStream())
{
byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody);
stream.Write(content, 0, content.Length);
}
authRequest.Headers.Add("Accept-Encoding", "gzip");
WebResponse authResponse = authRequest.GetResponse();
// deserialize into an object
TwitAuthenticateResponse twitAuthResponse;
using (authResponse)
{
using (var reader = new StreamReader(authResponse.GetResponseStream()))
{
JavaScriptSerializer js = new JavaScriptSerializer();
var objectText = reader.ReadToEnd();
twitAuthResponse = JsonConvert.DeserializeObject<TwitAuthenticateResponse>(objectText);
}
}
//now we have been granted access and got a token type with authorization token from Twitter
//in the form of a TwitAuthenticateResponse object, we can retrieve the data recursively with a cursor
CallData(twitAuthResponse, authHeader, cursor);
int totalFollowers = listFollowers.Count;
lblTotalFollowers.Text = screen_name + " has " + listFollowers.Count + " Followers";
Random objRnd = new Random();
List<TwiterFollowers> randomFollowers = listFollowers.OrderBy(item => objRnd.Next()).ToList<TwiterFollowers>();
foreach (TwiterFollowers tw in randomFollowers)
{
strTwiterFollowers = strTwiterFollowers + "<li><a target='_blank' title='" + tw.ScreenName + "' href=https://twitter.com/" + tw.ScreenName + "><img src='" + tw.ProfileImage + "'/><span>" + tw.ScreenName + "</span></a></li>";
}
}
//Retrieve the data from Twitter recursively with a cursor
private void CallData(TwitAuthenticateResponse twitAuthResponse, string authHeader, string cursor)
{
try {
JObject j = GetJSonObject(twitAuthResponse, authHeader, cursor);
JArray data = (JArray)j["users"];
if (data != null)
{
foreach (var item in data)
{
TwiterFollowers objTwiterFollowers = new TwiterFollowers();
objTwiterFollowers.ScreenName = item["screen_name"].ToString().Replace("\"", "");
objTwiterFollowers.ProfileImage = item["profile_image_url"].ToString().Replace("\"", "");
objTwiterFollowers.UserId = item["id"].ToString().Replace("\"", "");
listFollowers.Add(objTwiterFollowers);
}
JValue next_cursor = (JValue)j["next_cursor"];
if (long.Parse(next_cursor.Value.ToString()) > 0)
{
//Get the following data from Twitter with the next cursor
CallData(twitAuthResponse, authHeader, next_cursor.Value.ToString());
}
}
} catch (Exception ex)
{
//do nothing
}
}
private JObject GetJSonObject(TwitAuthenticateResponse twitAuthResponse, string authHeader, string cursor)
{
string resource_url = string.Format(resource_urlFormat, screen_name, cursor);
if (string.IsNullOrEmpty(cursor))
{
resource_url = resource_url.Substring(0, resource_url.IndexOf("&cursor"));
}
HttpWebRequest fRequest = (HttpWebRequest)WebRequest.Create(resource_url);
var timelineHeaderFormat = "{0} {1}";
fRequest.Headers.Add("Authorization", string.Format(timelineHeaderFormat, twitAuthResponse.token_type, twitAuthResponse.access_token));
fRequest.Method = "Get";
WebResponse response = fRequest.GetResponse();
string result = new StreamReader(response.GetResponseStream()).ReadToEnd();
return JObject.Parse(result);
}
private string GetVariableName<T>(Expression<Func<T>> expr)
{
var body = (MemberExpression)expr.Body;
return body.Member.Name;
}
private class TwitAuthenticateResponse
{
public string token_type { get; set; }
public string access_token { get; set; }
}
private class TwiterFollowers
{
public string ScreenName { get; set; }
public string ProfileImage { get; set; }
public string UserId { get; set; }
}
}
这篇关于如何使用游标在 Twitter API 中使用 c# 遍历 GET 关注者/列表的结果集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!