/// <summary> /// Generates a url to search with. /// </summary> /// <param name="method"></param> /// <param name="search"></param> /// <param name="min"></param> /// <param name="includeRetweets"></param> /// <returns></returns> private static Uri GenerateQuery(TwitterGatheringMethod method, string search, string min, bool includeRetweets) { switch (method) { //Why does Twitter's public search API have to be so terrible? //Is it maybe to make people not use it, and instead use the actual API? case TwitterGatheringMethod.Search: if (min?.Length == 0) { return(new Uri("https://twitter.com/search" + "?f=tweets" + "&vertical=default" + $"&q={WebUtility.UrlEncode(search)}")); } return(new Uri("https://twitter.com/i/search/timeline" + "?f=tweets" + "&vertical=default" + "&include_available_features=1" + "&include_entities=1" + "&reset_error_state=false" + "&src=typd" + $"&max_position={min}" + $"&q={WebUtility.UrlEncode(search)}")); case TwitterGatheringMethod.User: var query = $"https://twitter.com/i/profiles/show/{search}/" + $"{(includeRetweets ? "timeline" : "media_timeline")}" + "?include_available_features=1" + "&include_entities=1" + "&reset_error_state=false"; if (min != "") { query += $"&max_position={min}"; } return(new Uri(query)); default: throw new ArgumentException("Invalid gathering method supplied."); } }
/// <summary> /// Creates an instance of <see cref="TwitterScrapedPage"/>. /// </summary> /// <param name="method"></param> /// <param name="text"></param> public TwitterScrapedPage(TwitterGatheringMethod method, string text) { switch (method) { //Brackets because otherwise jObj is in same space each time case TwitterGatheringMethod.Search: { try { var jObj = JObject.Parse(text); Items = GetPostsFromHtml(UnescapeHtml(jObj["items_html"].ToObject <string>())); MinimumPosition = jObj["min_position"].ToObject <string>(); HasMoreItems = Items.Count > 0; //For some reason this field is always false in the json } catch (JsonReaderException) { Items = GetPostsFromHtml(text); MinimumPosition = $"TWEET-{Items.Last().Id}-{Items[0].Id}"; HasMoreItems = true; //Just assume it's true } return; } case TwitterGatheringMethod.User: { var jObj = JObject.Parse(text); Items = GetPostsFromHtml(UnescapeHtml(jObj["items_html"].ToObject <string>())); MinimumPosition = jObj["min_position"]?.ToObject <string>() ?? Items.Last().Id; HasMoreItems = jObj["has_more_items"].ToObject <bool>(); return; } default: throw new ArgumentException("Invalid method supplied."); } }