2017-07-28 87 views
-1

因此,我最近开始学习Visual Basic,并正在测试解析HTML数据的乐趣。当我进入一些JSON时,我下载了牛顿软件包并开始了解它的工作原理。我开始只是试图获取任何用户的Instagram页面的URL,但出现了一个我似乎无法解决的错误,而且我刚刚接触VB,我认为最好是寻求一些帮助,而不是困惑我的思维。Visual Basic Json.net Newtonsoft.Json.JsonReaderException错误

下面是代码:

Imports HtmlAgilityPack 
Imports Newtonsoft.Json 

Module Module1 

    Sub Main() 
     Dim user As String = Console.ReadLine() 
     Dim html = "https://www.instagram.com/" + user 
     Console.WriteLine(html) 
     Dim web As New HtmlWeb() 
     Dim htmlDoc = web.Load(html) 
     For Each node As HtmlNode In htmlDoc.DocumentNode.SelectNodes("//script[@type='text/javascript']") 
      If node.InnerHtml.Contains("profile_pic_url_hd") Then 'Makes sure the correct javascript code is used. 
       Dim json = node.InnerHtml.Substring(21, node.InnerHtml.Length - 21) 'Deletes the non Json code in the javascript. 
       Dim m As User = JsonConvert.DeserializeObject(Of User)(json) 'Error is here 
       Dim picture As String = m.profile_pic_url_hd 
       Console.WriteLine(picture) 
       Console.ReadLine() 
      Else 
       Console.WriteLine("Could not find correct code! Possibly because the username doesn't exist") 
      End If 
     Next 
     Console.WriteLine() 
    End Sub 

    Public Class User 
     Public Property biography As String 
     Public Property blocked_by_viewer As Boolean 
     Public Property country_block As Boolean 
     Public Property external_url As Object 
     Public Property external_url_linkshimmed As Object 
     Public Property followed_by As Integer 
     Public Property followed_by_viewer As Boolean 
     Public Property follows As Integer 
     Public Property follows_viewer As Boolean 
     Public Property full_name As String 
     Public Property has_blocked_viewer As Boolean 
     Public Property has_requested_viewer As Boolean 
     Public Property id As String 
     Public Property is_private As Boolean 
     Public Property is_verified As Boolean 
     Public Property profile_pic_url As String 
     Public Property profile_pic_url_hd As String 
     Public Property requested_by_viewer As Boolean 
     Public Property username As String 
     Public Property connected_fb_page As Object 
     Public Property media As Object 
    End Class 
End Module 

所以我就在这行错误:

Dim m As User = JsonConvert.DeserializeObject(Of User)(json) 

说:Newtonsoft.Json.JsonReaderException:“附加文本遇到结束后读取JSON内容: ;。路径“,第1行,位置3220。 位置号码总是变化。但我不确定为什么会发生这种情况。

任何帮助我感谢!

编辑: JSON的是各位的Instagram帐户不同,但作为一个例子这里是国际足联的JSON: https://pastebin.com/J3U0uz4S

+0

这将有助于张贴JSON - 也'作为Object'看起来很可疑。这通常意味着一个没有在JSON中表示的类型。 – Plutonix

回答

1

有几个问题在这里。

主要问题是您的JSON字符串在最终右大括号之后以分号字符(;)结尾,而这不是有效的JSON。 (请参阅JSON.org。)解析器显然不期待这样,所以它会抛出一个异常,告诉您在JSON结束后还有其他文本(分号)。所以你需要在反序列化之前去掉这个额外的字符。

json = json.TrimEnd(";") 

解决该问题后,第二个问题是您的模型与JSON不匹配。它看起来像是试图反序列化user数据,但是这些数据在JSON中嵌套了几个级别。你需要类来表示这些外层。您不一定需要在每个级别添加每个属性 - 只是您感兴趣的属性 - 但您确实需要从根到目标对象的所有级别,以便正确地反序列化它。

顺便说一句,Visual Studio具有可以从JSON样本为您生成类的功能。只需将您的JSON复制到剪贴板,然后从Edit -> Paste Special菜单中选择Paste JSON As Classes即可。注意这个工具不是万无一失的;生成的类有时需要一些手动更正。特别是,该工具不正确地生成数组属性。但是,当你使用复杂的JSON结构时,它可以给你一个很大的开端。

以下是最低类结构,您需要反序列化来自JSON的基本user数据。 (请注意,我遗漏了media属性;如果要获取该数据,则需要定义更多的类。)

Public Class Rootobject 
    Public Property entry_data As Entry_Data 
End Class 

Public Class Entry_Data 
    Public Property ProfilePage As List(Of Profilepage) 
End Class 

Public Class Profilepage 
    Public Property user As User 
End Class 

Public Class User 
    Public Property biography As String 
    Public Property blocked_by_viewer As Boolean 
    Public Property country_block As Boolean 
    Public Property external_url As String 
    Public Property external_url_linkshimmed As String 
    Public Property followed_by As Followed_By 
    Public Property followed_by_viewer As Boolean 
    Public Property follows As Follows 
    Public Property follows_viewer As Boolean 
    Public Property full_name As String 
    Public Property has_blocked_viewer As Boolean 
    Public Property has_requested_viewer As Boolean 
    Public Property id As String 
    Public Property is_private As Boolean 
    Public Property is_verified As Boolean 
    Public Property profile_pic_url As String 
    Public Property profile_pic_url_hd As String 
    Public Property requested_by_viewer As Boolean 
    Public Property username As String 
    Public Property connected_fb_page As Object 
End Class 

Public Class Followed_By 
    Public Property count As Integer 
End Class 

Public Class Follows 
    Public Property count As Integer 
End Class 

一旦你有,你可以反序列化和获取资料图片如下:

' Deserialize into the Rootobject class 
Dim root As Rootobject = JsonConvert.DeserializeObject(Of Rootobject)(json) 

' Drill down to get the profile pic 
Dim picture As String = root.entry_data.ProfilePage(0).user.profile_pic_url_hd 

小提琴:https://dotnetfiddle.net/dNLXDx

+0

谢谢,这非常有帮助,正是我所期待的。我现在对未来的企业有了更深的理解。 – 1ben99

+0

没问题;很高兴我能帮上忙。 –