public ICollection<AnimeStreamInfo> GetAnimeStreamInfo() { string responseBody; using (CompressionWebClient client = new CompressionWebClient()) { responseBody = client.DownloadString(Url); } // HTML Agility Pack does not convert "Ä" to an A with an umlaut // but it doesn't really matter as long as it's readable by the human editing the csv and consistent across program runs. HtmlDocument htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(responseBody); HtmlNodeCollection matchingNodes = htmlDoc.DocumentNode.SelectNodes(XPath); List<AnimeStreamInfo> streams = new List<AnimeStreamInfo>(); foreach (HtmlNode matchingNode in matchingNodes) { AnimeStreamInfo stream = GetStreamInfoFromMatch(matchingNode); // Convert possibly relative url to an absolute url stream = new AnimeStreamInfo(stream.AnimeName, Utils.PossiblyRelativeUrlToAbsoluteUrl(stream.Url, Url), stream.Service); streams.Add(stream); } return streams; }
private void EnsureOauthToken() { if(_oauthToken != null) return; using (CompressionWebClient webClient = new CompressionWebClient()) { string huluPageHtml = webClient.DownloadString("http://www.hulu.com/tv/genres/anime"); Regex oathTokenRegex = new Regex("w.API_DONUT = '(?<Token>[^']*)'"); Match m = oathTokenRegex.Match(huluPageHtml); if (!m.Success) { throw new Exception("w.API_DONUT not found in Hulu HTML. The page probably changed and the code for getting Hulu anime needs to be updaed."); } _oauthToken = m.Groups["Token"].ToString(); } }
/// <summary> /// /// </summary> /// <param name="type">movies or shows</param> /// <param name="genre"></param> /// <returns></returns> private ICollection<AnimeStreamInfo> GetAnimeStreamInfo(string type, string genre) { // http://www.hulu.com/mozart/v1.h2o/shows?exclude_hulu_content=1&genre={genre}&sort=release_with_popularity&_language=en&_region=us&items_per_page=100&position=0®ion=us&locale=en&language=en&access_token={oathtoken} // count is in total_count // process results: // data[x].show.name, data[x].show.canonical_name // current position += num results processed // if current position < count, repeat // // data[x].show.name is the show's name. // data[x].show.canonical_name is how you get the url for the show - http://www.hulu.com/{canonical_name} EnsureOauthToken(); List<AnimeStreamInfo> streams = new List<AnimeStreamInfo>(); using (CompressionWebClient webClient = new CompressionWebClient()) { int position = 0; int numAnimes = int.MaxValue; while (position < numAnimes) { string url = string.Format( CultureInfo.InvariantCulture, "http://www.hulu.com/mozart/v1.h2o/{0}?exclude_hulu_content=1&genre={1}&sort=release_with_popularity&_language=en&_region=us&items_per_page=100&position={2}®ion=us&locale=en&language=en&access_token={3}", type, Uri.EscapeDataString(genre), position, Uri.EscapeDataString(_oauthToken)); string jsonString = webClient.DownloadString(url); HuluAnimeResultsJsonRoot json = JsonConvert.DeserializeObject<HuluAnimeResultsJsonRoot>(jsonString); if (json.data.Count == 0) { throw new Exception(string.Format("Did not get any hulu anime from url {0}", url)); } numAnimes = json.total_count; foreach (var data in json.data) { string animeName = data.show.name; string animeUrl = string.Format("http://www.hulu.com/{0}", data.show.canonical_name); streams.Add(new AnimeStreamInfo(animeName: animeName, url: animeUrl, service: StreamingService.Hulu)); position++; } } } return streams; }