2017-07-28 13 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。 ' ポジション番号は常に変更されます。しかし、なぜこれが起きているのか分かりません。

私はありがとうございました!

編集:問題のカップルがここにあります https://pastebin.com/J3U0uz4S

+0

それはJSONを投稿する助けになる - また 'Object'として疑わしいと思われる。これは通常、JSONで表現されていないTypeを意味します。 – Plutonix

答えて

1

: JSONは皆さんInstagramのアカウントに異なるが、一例としては、ここではFIFAワールドカップのJSONです。

主な問題は、有効なJSONではない最後の閉じ括弧の後にJSON文字列がセミコロン文字(;)で終了することです。 (JSON.orgを参照してください)パーサーは明らかにこれを期待していないので、JSONの内容の後に追加のテキスト(セミコロン)があることを伝える例外がスローされています。したがって、デシリアライズする前にこの余分な文字を取り除く必要があります。

json = json.TrimEnd(";") 

これを修正すると、2番目の問題はモデルが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

問題ありません。お役に立てて嬉しいです。 –