c# - 如何在 JObject 的 StreamReader 中列出所有“项目”?
问题描述
如何从 JObject 中的 StreamReader 检索“totalResult”?在“JO”变量中,我只得到 50 个值,但总数说它有 227 个值。
string link = "https://www.youtube.com/playlist?list=PLTPg64KdGgYivEK9avhUlxsaJhD0TfpxW";
string Url = String.Format("https://api.youtubemultidownloader.com/playlist?url={0}&nextPageToken=", link);
HttpWebRequest wb = (HttpWebRequest)WebRequest.Create(Url);
wb.Method = "GET";
wb.KeepAlive = true;
wb.Proxy = null;
wb.Referer = "https://youtubemultidownloader.com/playlist.html";
wb.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0";
var value = new StreamReader(wb.GetResponse().GetResponseStream()).ReadToEnd();
JObject JO = JObject.Parse(value);
JObject Videos = JObject.Parse(JO["items"].ToString());
为了更清楚起见,我正在尝试从 YouTube 播放列表中恢复所有视频,为此我依赖此站点youtubemultidownloader.com的 API ,这意味着所有视频都在变量“value”中然后传递给“JO”变量,最后从“Videos”变量中获取 Children()。
如何获得“totalResults”的所有“项目”?因为“项目”的总数应该是播放列表中的视频总数。我总共有 227 个播放列表的视频,但是当我计算视频变量中的“项目”时,只显示 50 个。
int count = Videos.Count;
var RetDic = new Dictionary<string, string>();
foreach (var v in Videos.Children())
{
string Video_ID = v.First["id"].ToString();
string Video_Title = v.First["title"].ToString();
RetDic.Add(Video_ID, Video_Title);
}
我正在使用“Newtonsoft.Json.6.0.6”包
解决方案
您的问题是关于 api 的分页,请查看"resultsPerPage": 50
您使用的下载器页面,
获得第一个结果,如果总计 > resultPerPage som 它使用"nextPageToken":"CGQQAA"
示例 146 项(总计)发出新请求 - > 3 请求 50 没有 nextPageToken 返回 nextpageToken
string.Format("https://api.yoursite.com/playlist?url={0}&nextPageToken=", link)
使用 nextpagetoken 发出请求的 50 秒视频包
string.Format("https://api.yoursite.com/playlist?url={0}&nextPageToken={1}", link, nextPageToken)
Json 结果示例
{
"nextPageToken":"CGQQAA",
"totalResults":146,
"resultsPerPage":50,
"currentResults":50,
"items":{
"0":{
"id":"wh-uYV6YprA",
"title":"Private video"
},
"1":{
"id":"C6H0emVJtSw",
"title":"Ya No Entiendo Nada - Al2 (2010) Los Aldeanos"
},
"2":{
"id":"mhHES-k7Trg",
"title":"El B [Los Aldeanos]- America"
},
/* ... */
"47":{
"id":"0IbK43e3vXs",
"title":"VIOLADORES DEL VERSO - 8 LINEAS (CANAL BOA)"
},
"48":{
"id":"6xCL98XMq9Q",
"title":"SFDK (Zatu) - Cuando todo acabe (con El Chojin - Colabora Jefe De La M) [Lista de invitados(2011)]"
},
"49":{
"id":"31WFa51c4Lk",
"title":"Nach - Los Años Luz (con Diana Feria) - Un Dia En Suburbia"
}
},
"status":true
}
你可以做一些这样的
var playlist = GetPlayList("https://www.youtube.com/playlist?list=PLTPg64KdGgYivEK9avhUlxsaJhD0TfpxW");
Console.WriteLine(string.Join(playlist.Items.ToList()))
public string MakeRequest(string link, string nextPage="")
{
string url = string.Format("https://api.youtubemultidownloader.com/playlist?url={0}&nextPageToken={1}", link, nextPage);
HttpWebRequest wb = (HttpWebRequest)WebRequest.Create(url);
wb.Method = "GET";
wb.KeepAlive = true;
wb.Proxy = null;
wb.Referer = "https://youtubemultidownloader.com/playlist.html";
wb.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0";
var value = new StreamReader(wb.GetResponse().GetResponseStream()).ReadToEnd();
return value;
}
public PlayList GetPlayList(string link)
{
var json = MakeRequest(link);
var playList = PlayList.FromJson(json);
while (playList.Items.Count < playList.TotalResults)
{
json = MakeRequest(link, playList.NextPageToken);
var newPagePlayList = PlayList.FromJson(json);
playList.NextPageToken = newPagePlayList.NextPageToken;
// playList.Items = playList.Items.Concat(newPagePlayList.Items).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
var index = 1;
playList.Items = playList.Items.Concat(newPagePlayList.Items).ToDictionary((kvp) => (index++).ToString(), kvp => kvp.Value);
}
return playList;
}
转换器
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class PlayList
{
[JsonProperty("totalResults")]
public long TotalResults { get; set; }
[JsonProperty("resultsPerPage")]
public long ResultsPerPage { get; set; }
[JsonProperty("nextPageToken")]
public string NextPageToken { get; set; }
[JsonProperty("currentResults")]
public long CurrentResults { get; set; }
[JsonProperty("items")]
public Dictionary<string, Item> Items { get; set; }
[JsonProperty("status")]
public bool Status { get; set; }
}
public partial class Item
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
public override string ToString() {
return string.Format("{0} -> {1}", Id, Title);
}
}
public partial class PlayList
{
public static PlayList FromJson(string json) => JsonConvert.DeserializeObject<PlayList>(json, Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this PlayList self) => JsonConvert.SerializeObject(self, Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters = {
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
更新 2018/8/06 按请求更新连接项,修复重复键
推荐阅读
- sql - PostgreSQL - 获取按日期时间列分组的表中 N 个间隔的项目计数
- javascript - 使用 Google API 检索与我的 API 相关的用户数据
- python - 无法在python中编写条件来更新字典值
- python - 如何使用 Python 3.6 在 Windows 10 中设置壁纸?
- mysql - Mysql TIMESTAMPDIFF 用于时间数据类型返回负值
- c# - 从 DB 通用函数读取数据
- python - 在 python 中将 web 中的 excel 文件保存为 excel 文件
- javascript - 在 Linux 上使用 asar 运行电子应用程序 /Cannot GET index.html
- android - 每个项目的动态ViewPager2高度计算
- typescript - 如何在 Typescript 中向导入的库模块添加新方法/属性?