Code Bye

从豆瓣抓取的JSON数据如何用C#解析成对象

读取http://api.douban.com/v2/movie/subject/25870084可以获得
{"rating":{"max":10,"average":7.4,"stars":"40","min":0},"reviews_count":990,"wish_count":16073,"collect_count":64690,"douban_site":"http:\/\/site.douban.com\/MissGranny\/","year":"2015","images":{"small":"http:\/\/img3.douban.com\/view\/movie_poster_cover\/ipst\/public\/p2219440250.jpg","large":"http:\/\/img3.douban.com\/view\/movie_poster_cover\/lpst\/public\/p2219440250.jpg","medium":"http:\/\/img3.douban.com\/view\/movie_poster_cover\/spst\/public\/p2219440250.jpg"},"alt":"http:\/\/movie.douban.com\/subject\/25870084\/","id":"25870084","mobile_url":"http:\/\/movie.douban.com\/subject\/25870084\/mobile","title":"重返20岁","do_count":null,"seasons_count":null,"schedule_url":"http:\/\/movie.douban.com\/subject\/25870084\/cinema\/","episodes_count":null,"genres":["喜剧","爱情","奇幻"],"countries":["中国大陆","韩国","台湾","香港"],"casts":[{"avatars":{"small":"http:\/\/img3.douban.com\/img\/celebrity\/small\/1360212531.4.jpg","large":"http:\/\/img3.douban.com\/img\/celebrity\/large\/1360212531.4.jpg","medium":"http:\/\/img3.douban.com\/img\/celebrity\/medium\/1360212531.4.jpg"},"alt":"http:\/\/movie.douban.com\/celebrity\/1312862\/","id":"1312862","name":"杨子姗"},{"avatars":{"small":"http:\/\/img5.douban.com\/img\/celebrity\/small\/44939.jpg","large":"http:\/\/img5.douban.com\/img\/celebrity\/large\/44939.jpg","medium":"http:\/\/img5.douban.com\/img\/celebrity\/medium\/44939.jpg"},"alt":"http:\/\/movie.douban.com\/celebrity\/1058399\/","id":"1058399","name":"归亚蕾"},{"avatars":{"small":"http:\/\/img3.douban.com\/img\/celebrity\/small\/22033.jpg","large":"http:\/\/img3.douban.com\/img\/celebrity\/large\/22033.jpg","medium":"http:\/\/img3.douban.com\/img\/celebrity\/medium\/22033.jpg"},"alt":"http:\/\/movie.douban.com\/celebrity\/1211987\/","id":"1211987","name":"陈柏霖"},{"avatars":{"small":"http:\/\/img5.douban.com\/img\/celebrity\/small\/1388465430.97.jpg","large":"http:\/\/img5.douban.com\/img\/celebrity\/large\/1388465430.97.jpg","medium":"http:\/\/img5.douban.com\/img\/celebrity\/medium\/1388465430.97.jpg"},"alt":"http:\/\/movie.douban.com\/celebrity\/1337001\/","id":"1337001","name":"鹿晗"}],"current_season":null,"original_title":"重返20岁","summary":"七十岁的老太太沈梦君(归亚蕾 饰)年纪越大,脾气越大,渐渐的,除了管家李大海(王德顺 饰)还愿意留在她的身边,没有一个人愿意与她共处。在儿媳妇杨琴(李宜娟 饰)因压力过大而生病入院后,沈梦君终于被家人送入了养老院,气愤和悲伤之中,沈梦君决定在照相馆里留下自己最后的容颜,没想到却因此而开启了一段返老还童的奇幻旅程。\n一眨眼之间,满面皱纹的沈梦君变成了二十岁的妙龄少女孟丽君(杨子珊 饰),重获青春的沈梦君不仅体会到了年轻带来的机遇与活力,更品尝到了爱情的酸涩滋味。然而,就在她沉浸在幸福的幻觉中不能自拔之时,一场意外将她抛到了人生的十字路口之前,二十岁还是七十岁,沈梦君必须做出选择。?豆瓣","subtype":"movie","directors":[{"avatars":{"small":"http:\/\/img5.douban.com\/img\/celebrity\/small\/1369639357.39.jpg","large":"http:\/\/img5.douban.com\/img\/celebrity\/large\/1369639357.39.jpg","medium":"http:\/\/img5.douban.com\/img\/celebrity\/medium\/1369639357.39.jpg"},"alt":"http:\/\/movie.douban.com\/celebrity\/1189801\/","id":"1189801","name":"陈正道"}],"comments_count":32768,"ratings_count":58928,"aka":["重返二十岁","20?? ?? ? ?","Miss Granny","20 Once Again"]}

我试用了C#自带的DataContractJsonSerializer和Newtonsoft.Json,感觉Newtonsoft.Json好用一些。
海报比较容易获取,大海报是
            JObject jo = (JObject)JsonConvert.DeserializeObject(srcString);
            string large = jo[“images”][“large”].ToString();
详细的api介绍可见http://developers.douban.com/wiki/?title=movie_v2
只会C#,JAVA啥的都没有学过,第一次接触JSON,对于页面上所谓的dict和array数据类型均不熟悉,不知道如何用C#处理
casts字段为array,rating字段为dict,如何能用比较规则的写法,变成对应的C#类型??

1. 页面上哪里有什么“dict类型”?贴出来。
2. 你既然使用了 JObject,应该也可以使用 JArray。
3. 要“变成对应的C#类型”,那么你应该自己写出class定义来。你的数据,可能需要定义3、4个class。如果没有自定义的对象与json之间的序列化/反序列的概念,那么先抽出2天时间从基础把它理解清楚,多看一些.net对象与json文本序列化/反序列化的例子并且自己实验,先不要勉强地硬要别人给你写你的这个东西。估计你完全不懂的东西,别人是不会随便给你写的。
1.rating  评分,见附录  dict——api说明
“rating”:{“max”:10,”average”:7.3,”stars”:”40″,”min”:0}
这个按照网页上说明是dict类型。
JArray昨天测试过,不成功。
测试1
avatars = jo[“avatars”][0][“name”].ToString();
失败
测试2
JToken a = jo[“avatars”];
string[] b = a.ToArray<>;——这个好像是LINQ语法
失败
3.具体就是我不知道用什么类型去对应dict。C#的dictorary用过一次,不熟。array也不知道怎么弄。
我自己尝试抓取了imdb的数据,imdbapi提供的json很容易,我直接用C#自带的DataContractJsonSerializer就搞定了,但是豆瓣的要复杂很多,我先尝试写了douban类,发现完全不知道怎么弄对应的类型。

60分
这种东西先用现成的转换工具把json转c#的类,比如:http://jsonutils.com/。当然它不是那么智能,自己再调整下就好。弄好以后如下:
pre class=”brush: csharp”>
public class Rating
{
    public int Min { get; set; }
    public int Max { get; set; }
    public double Average { get; set; }
    public string Stars { get; set; }
}
public class Celebrity
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Alt { get; set; }
    public Images Avatars { get; set; }
}
public class Images
{
    public string Small { get; set; }
    public string Large { get; set; }
    public string Medium { get; set; }
}
public class Movie
{
    public string Id { get; set; }
    public string Title { get; set; }
    [JsonProperty(“original_title”)]
    public string OriginalTitle { get; set; }
    public IList<string> Aka { get; set; }
    public string Alt { get; set; }
    [JsonProperty(“mobile_url”)]
    public string MobileUrl { get; set; }
    public Rating Rating { get; set; }
    [JsonProperty(“ratings_count”)]
    public int RatingsCount { get; set; }
    [JsonProperty(“wish_count”)]
    public int WishCount { get; set; }
    [JsonProperty(“collect_count”)]
    public int CollectCount { get; set; }
    [JsonProperty(“do_count”)]
    public int? DoCount { get; set; }
    public Images Images { get; set; }
    public string Subtype { get; set; }
    public IList<Celebrity> Directors { get; set; }
    public IList<Celebrity> Casts { get; set; }
    [JsonProperty(“douban_site”)]
    public string DoubanSite { get; set; }
    public string Year { get; set; }
    public IList<string> Genres { get; set; }
    public IList<string> Countries { get; set; }
    public string Summary { get; set; }
    
    [JsonProperty(“comments_count”)]
    public int CommentsCount { get; set; }
    [JsonProperty(“reviews_count”)]
    public int ReviewsCount { get; set; }
    [JsonProperty(“seasons_count”)]
    public int? SeasonsCount { get; set; }
    [JsonProperty(“current_season”)]
    public int? CurrentSeason { get; set; }
    [JsonProperty(“episodes_count”)]
    public int? EpisodesCount { get; set; }
    [JsonProperty(“schedule_url”)]
    public string ScheduleUrl { get; set; }
}
// 使用的时候
var movie = JsonConvert.DeserializeObject<Movie>(jsonText);
/pre>
PS:还需要注意,在你给的json里面,最后的韩文变成了问号,估计这是用ansi方式保存了原本是utf8的文字导致的,应该以utf8方式保存。
数组定位错了,改下
jo[“casts”][0][“avatars”][“name”].ToString();
杨子姗name=jo.casts[0].avatars.name
晕jo.casts[0].name 这下应该没错了
嗯,其实那天后来根据5楼的回复,我自己完成了一个类,直接拿来序列化即可。
pre class=”brush: csharp”>
[DataContract]
    public class douban
    {
        [DataMember(Order = 0)]
        public rating rating { get; set; }
        [DataMember(Order = 1)]
        public string reviews_count { get; set; }
        [DataMember(Order = 2)]
        public string wish_count { get; set; }
        [DataMember(Order = 3)]
        public string collect_count { get; set; }
        [DataMember(Order = 4)]
        public string douban_site { get; set; }
        [DataMember(Order = 5)]
        public string year { get; set; }
        [DataMember(Order = 6)]
        public images images { get; set; }
        [DataMember(Order = 7)]
        public string alt { get; set; }
        [DataMember(Order = 8)]
        public string id { get; set; }
        [DataMember(Order = 9)]
        public string mobile_url { get; set; }
        [DataMember(Order = 10)]
        public string title { get; set; }
        [DataMember(Order = 11)]
        public string do_count { get; set; }
        [DataMember(Order = 12)]
        public string seasons_count { get; set; }
        [DataMember(Order = 13)]
        public string schedule_url { get; set; }
        [DataMember(Order = 14)]
        public string episodes_count { get; set; }
        [DataMember(Order = 15)]
        public string[] genres { get; set; }
        [DataMember(Order = 16)]
        public string[] countries { get; set; }
        [DataMember(Order = 17)]
        public List<people_class> casts { get; set; }
        [DataMember(Order = 18)]
        public string current_season { get; set; }
        [DataMember(Order = 19)]
        public string original_title { get; set; }
        [DataMember(Order = 20)]
        public string summary { get; set; }
        [DataMember(Order = 21)]
        public string subtype { get; set; }
        [DataMember(Order = 22)]
        public List<people_class> directors { get; set; }
        [DataMember(Order = 23)]
        public string comments_count { get; set; }
        [DataMember(Order = 24)]
        public string ratings_count { get; set; }
        [DataMember(Order = 25)]
        public string[] aka { get; set; }
    }
    public struct rating
    {
        public string max { get; set; }
        public string average { get; set; }
        public string stars { get; set; }
        public string min { get; set; }
    };
    public struct images
    {
        public string small { get; set; }
        public string large { get; set; }
        public string medium { get; set; }
    };
    public class people_class
    {
        public List<images> avatars { get; set; }
        public string alt { get; set; }
        public string id { get; set; }
        public string name { get; set; }
    }
/pre>
直接拿来序列化
pre class=”brush: csharp”>douban db = JSON.parse<douban>(srcString);

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明从豆瓣抓取的JSON数据如何用C#解析成对象