最近在写一个桌面的豆瓣电台程序,在解析其DJ电台的频道列表时,在网页中抓取的js代码如下:
channelInfo.dj = [{"channel_id":"l3","name":"谁的成名曲"},{"channel_id":"113044","name":"浅谈轻唱","timestamp":"1333103365.0","update":0},{"channel_id":"115987","name":"爵士之音","timestamp":"1333952457.0","update":0},{"channel_id":"106379","name":"萌得耳松","timestamp":"1330493624.0","update":0},{"channel_id":"116154","name":"子寒Ann","timestamp":"1334220284.0","update":0},{"channel_id":"119300","name":"黑噪音","timestamp":"1332596519.0","update":0},{"channel_id":"103756","name":"周准","timestamp":"1310296419.0","update":0},{"channel_id":"113914","name":"苏比","timestamp":"1334727058.0","update":0},{"channel_id":"118974","name":"iPlay","timestamp":"1332410472.0","update":0},{"channel_id":"104001","name":"有待","timestamp":"1322014846.0","update":0},{"channel_id":"l1","name":"Facelook"},{"channel_id":"123048","name":"宅电波","timestamp":"1329186348.0","update":0},{"channel_id":"113380","name":"搁料广播","timestamp":"1335229294.0","update":0},{"channel_id":"104524","name":"FM O.U.R","timestamp":"1332233929.0","update":0},{"channel_id":"111880","name":"三角龙","timestamp":"1333598037.0","update":0},{"channel_id":"112177","name":"掌柜阿峻","timestamp":"1335334224.0","update":0},{"channel_id":"103547","name":"阿鹏","timestamp":"1317363315.0","update":0},{"channel_id":"106166","name":"离岸音乐电台","timestamp":"1329901317.0","update":0},{"channel_id":"119466","name":"Sorry! FM","timestamp":"1324311596.0","update":0},{"channel_id":"116241","name":"坏蛋调频","timestamp":"1328582570.0","update":0},{"channel_id":"l2","name":"磁带断了"},{"channel_id":"105062","name":"ACHA","timestamp":"1333435761.0","update":0},{"channel_id":"110186","name":"公告牌之外","timestamp":"1319694482.0","update":0},{"channel_id":"121068","name":"枣听乐纪","timestamp":"1325663931.0","update":0},{"channel_id":"114014","name":"Suburbs","timestamp":"1331610037.0","update":0},{"channel_id":"118673","name":"IndiePower","timestamp":"1333171142.0","update":0},{"channel_id":"121069","name":"666","timestamp":"1321876995.0","update":0},{"channel_id":"116351","name":"Rêveur Ailé","timestamp":"1329894116.0","update":0},{"channel_id":"120705","name":"糖蒜广播","timestamp":"1319420901.0","update":0},{"channel_id":"117447","name":"SICK RADIO","timestamp":"1323311571.0","update":0},{"channel_id":"121379","name":"电音中国","timestamp":"1328175960.0","update":0},{"channel_id":"118962","name":"CT-808","timestamp":"1308483701.0","update":0}];
要解析这段代码,涉及到几个知识点:1.正则表达式,要在网页中抓取相应的代码,必须会使用正则表达式。2.JSON的反序列化操作。
这里主要写一下自己在这两天中碰到的第二个问题:
这段代码不是典型的JSON对象,而是JSON对象数组。用JSON对象的解析方法不能达到预期想要的结果,编译器总是报“应为来自命名空间“”的元素“root”。。遇到名称为“”、命名空间为“”的“None”或“反序列化对象 属于类型 Doubaner.DBFM.DJChannel 时出现错误。遇到意外字符“c””。碰到这种错误,编译器的提示多半对于解决问题没有多大的帮助,MSDN上也没有写的很清楚。
无奈,花了两天时间,也没想出较好的解决方法。最后是在网上搜到的类似的程序中看到了别人的解决方案:
在我们定义的反序列化操作的类中,新建一个类,继承自该类的List<T> 泛型,然后编译器便可正确的将该段代码反序列化。
下面是关键的几处代码:
DJChannels djc = new DJChannels();//这是自己定义的DJ频道列表的类,继承自List<DJChannel>
try
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DJChannels));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(match.Groups[1].Value));
//string a = new StreamReader(ms).ReadToEnd();
djc = (DJChannels)ser.ReadObject(ms);
}
catch (Exception ex)
{
LogUtil.Log(ex.ToString());
}
/// <summary>
/// DJ频道类
/// </summary>
[DataContract]
class DJChannel
{
/// <summary>
/// 频道ID
/// </summary>
[DataMember(Name="channel_id")]
public string channel {get;set;}
/// <summary>
/// 频道名
/// </summary>
[DataMember(Name="name")]
public string name {get;set;}
/// <summary>
///
/// </summary>
[DataMember]
public string timestamp { get; set; }
[DataMember]
public string update { get; set; }
}
internal class DJChannels : List<DJChannel> { }