【问题标题】:Visual Basic Json.net Newtonsoft.Json.JsonReaderException errorVisual Basic Json.net Newtonsoft.Json.JsonReaderException 错误
【发布时间】:2017-07-28 23:40:09
【问题描述】:

所以我最近开始学习 Visual Basic 并测试解析 HTML 数据只是为了找点乐子。当我接触到一些 JSON 时,我下载了 newton-soft pack 并开始学习它是如何工作的。我一开始只是试图获取任何用户 Instagram 页面的 URL,但遇到了一个我似乎无法解决的错误,而且我是 VB 的新手,我认为最好寻求一些帮助而不是让我的头脑疲倦。

代码如下:

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。 位置编号总是变化的。但我不确定为什么会发生这种情况。

感谢任何帮助!

编辑: 每个人的 Instagram 帐户的 Json 都不同,但这里以国际足联的 Json 为例: https://pastebin.com/J3U0uz4S

【问题讨论】:

  • 这将有助于发布 json - As Object 看起来也很可疑。这通常意味着 JSON 中没有表示的类型。

标签: json vb.net json.net instagram screen-scraping


【解决方案1】:

这里有几个问题。

主要问题是您的 JSON 字符串在最后一个右大括号后以分号字符 (;) 结尾,这不是有效的 JSON。 (见JSON.org。)解析器显然没有预料到这一点,所以它抛出一个异常,告诉你在JSON内容结束后还有额外的文本(分号)。所以你需要在反序列化之前去掉这个多余的字符。

json = json.TrimEnd(";")

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

顺便说一句,Visual Studio 具有可以从 JSON 示例为您生成类的功能。只需将您的 JSON 复制到剪贴板并从 Edit -> Paste Special 菜单中选择 Paste JSON As Classes。请注意,此工具并非万无一失;生成的类有时需要一些手动更正。特别是,该工具会错误地生成数组属性。但是,当您使用复杂的 JSON 结构时,它可以让您领先一步。

下面是 minimum 类结构,您需要从 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

【讨论】:

  • 谢谢,这非常有帮助,正是我想要的。我现在对未来的创业有了更深入的了解。
  • 没问题;很高兴我能帮上忙。
猜你喜欢
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-10
  • 1970-01-01
相关资源
最近更新 更多