首页 > 解决方案 > 如何在 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”包

标签: c#jsonapijson.net

解决方案


您的问题是关于 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 按请求更新连接项,修复重复键


推荐阅读