2016-09-13 7 views
1

3社から最新の株価を取得しようとしていますが、数字を正しく取得できないようです。私はGoogleのファイナンスをこすり、私はこれに似たオブジェクトを取得したシンボルを取得することができます:Google Financial JSON文字列を逆シリアル化する

// [ { "id": "983582" ,"t" : ".DJI" ,"e" : "INDEXDJX" ,"l" : "18,051.10" ,"l_fix" : "18051.10" ,"l_cur" : "18,051.10" ,"s": "0" ,"ltt":"3:15PM EDT" ,"lt" : "Sep 13, 3:15PM EDT" ,"lt_dts" : "2016-09-13T15:15:39Z" ,"c" : "-273.97" ,"c_fix" : "-273.97" ,"cp" : "-1.50" ,"cp_fix" : "-1.50" ,"ccol" : "chr" ,"pcls_fix" : "18325.07" } ] 

と、私は「18,051.10」である第四コロン、後にアイテムを取得し、残りを無効にして置くしようとしていますその二重の値を配列に戻すことができますので、ラベルに表示することはできますが運はありません。私は、会社の株価グラフの履歴を返すサンプルプログラムを練習しようとしているnoobプログラマーですが、ただ最新の見積もりを返すだけです。

Imports System.Net 
Imports System.IO 
Imports System.Drawing.Drawing2D 

Public Class Form1 
' The ticker symbols. 
Private Symbols As List(Of String) = Nothing 

' The current prices. 
Private Prices() As List(Of Single) = Nothing 

' Redraw the graph. 
'Private Sub picGraph_Resize(ByVal sender As Object, ByVal e As System.EventArgs) 
' DrawGraph() 
'End Sub 

' Get the closing prices and graph them. 
Private Sub btnGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGo.Click 
    Me.Cursor = Cursors.WaitCursor 

    ' Get the ticker symbols. 
    'Dim symbols_text() As String = txtSymbols.Text.Split(","c) 
    Dim symbols_text() As String = {"PKG", "TEN", "INDU"} 
    Symbols = New List(Of String)() 
    For i As Integer = 0 To symbols_text.Length - 1 
     Symbols.Add(symbols_text(i).Trim()) 
    Next i 

    ' Get the data. 
    ReDim Prices(0 To Symbols.Count - 1) 
    For i As Integer = 0 To Symbols.Count - 1 
     Prices(i) = GetStockPrices(Symbols(i)) 
    Next i 

    ' Graph it. 
    'DrawGraph() 
    FillData() 
    Me.Cursor = Cursors.Default 
End Sub 

' Get the prices for this symbol. 
'Private Function GetStockPrices(ByVal symbol As String) As List(Of Single) 
' ' Compose the URL. 
' Dim url As String = "http://www.google.com/finance/historical?output=csv&q=" & symbol 

' ' Get the result. 
' ' Get the web response. 
' Dim result As String = GetWebResponse(url) 

' ' Get the historical prices. 
' Dim lines() As String = result.Split(_ 
'  New String() {vbCr, vbLf}, _ 
'  StringSplitOptions.RemoveEmptyEntries) 
' Dim prices As New List(Of Single)() 

' ' Process the lines, skipping the header. 
' For i As Integer = 1 To lines.Length - 1 
'  Dim line As String = lines(i) 
'  prices.Add(Single.Parse(line.Split(","c)(4))) 
' Next i 

' Return prices 
'End Function 

Public Function GetStockPrices(symbol As String) As List(Of Single) 
    ' Dim pricesArray() As String 
    Dim prices As New List(Of Single)() 
    Dim items() As GoogleFinanceItem 

    If UCase(symbol) = "INDU" Then 
     Dim url As String = "http://finance.google.com/finance/info?client=ig&q=INDEXDJX%3A.DJI" 
     Dim result As String = GetWebResponse(url) 
     ' Dim newResult = result.Substring(1, result.Length - 1) 
     items = JsonConvert.DeserializeObject(Of GoogleFinanceItem())(result) 
     ' pricesArray = Split(result, ":") 
    Else 
     Dim url As String = "http://finance.google.com/finance/info?client=ig&q=" & UCase(symbol) 
     Dim result As String = GetWebResponse(url) 
     ' Dim newResult = result.Substring(1, result.Length - 1) 
     items = JsonConvert.DeserializeObject(Of GoogleFinanceItem())(result) 
     ' pricesArray = Split(result, ":") 
    End If 
    ' pricesArray = Split(pricesArray(4), """") 

    ' prices.Add(CSng(Format(pricesArray(1), "0.00"))) 
    'prices.Add(CSng(Format(pricesArray(1)))) 
    prices.Add(CSng(items(0).price)) 
    Return prices 

End Function 

' Get a web response. 
Private Function GetWebResponse(ByVal url As String) As String 
    ' Make a WebClient. 
    Dim web_client As New WebClient() 

    ' Get the indicated URL. 
    Dim response As Stream = web_client.OpenRead(url) 

    ' Read the result. 
    Using stream_reader As New StreamReader(response) 
     ' Get the results. 
     Dim result As String = stream_reader.ReadToEnd() 

     ' Close the stream reader and its underlying stream. 
     stream_reader.Close() 

     ' Return the result. 
     Return result 
    End Using 
End Function 

Private Sub FillData() 
    Dim symbolSubSet() As Control = {Label1, Label2, Label3} 
    Dim priceSubSet() As Control = {Label4, Label5, Label6} 

    For i = 0 To 2 
     symbolSubSet(i).Text = Symbols(i) 
     priceSubSet(i).Text = Prices(i).ToString 
     Next 
End Sub 
' Draw the graph. 
'Private Sub DrawGraph() 
' If (Prices Is Nothing) Then Return 

' ' Make the bitmap. 
' Dim bm As New Bitmap(_ 
'  picGraph.ClientSize.Width, _ 
'  picGraph.ClientSize.Height) 
' Using gr As Graphics = Graphics.FromImage(bm) 
'  gr.Clear(Color.White) 
'  gr.SmoothingMode = SmoothingMode.AntiAlias 

'  ' Get the largest prices. 
'  Dim max_price As Single = 10 
'  For Each symbol_prices As List(Of Single) In Prices 
'   Dim new_max As Single = symbol_prices.Max() 
'   If (max_price < new_max) Then max_price = new_max 
'  Next symbol_prices 

'  ' Scale and translate the graph. 
'  Dim scale_x As Single = -picGraph.ClientSize.Width/CSng(Prices(0).Count) 
'  Dim scale_y As Single = -picGraph.ClientSize.Height/max_price 
'  gr.ScaleTransform(scale_x, scale_y) 
'  gr.TranslateTransform(_ 
'   picGraph.ClientSize.Width, _ 
'   picGraph.ClientSize.Height, _ 
'   System.Drawing.Drawing2D.MatrixOrder.Append) 

'  ' Draw the grid lines. 
'  Using string_format As New StringFormat() 
'   Using thin_pen As New Pen(Color.Gray, 0) 
'    For y As Integer = 0 To CInt(max_price) Step 10 
'     gr.DrawLine(thin_pen, 0, y, Prices(0).Count, y) 
'    Next y 
'    For x As Integer = 0 To Prices(0).Count - 1 Step 7 
'     gr.DrawLine(thin_pen, x, 0, x, 2) 
'    Next x 
'   End Using 
'  End Using 

'  ' Draw each symbol's prices. 
'  Dim colors() As Color = {Color.Black, Color.Red, Color.Green, Color.Blue, Color.Orange, Color.Purple} 
'  For symbol_num As Integer = 0 To Prices.Length - 1 
'   Dim symbol_prices As List(Of Single) = Prices(symbol_num) 

'   ' Make the data points. 
'   Dim points(0 To symbol_prices.Count - 1) As PointF 
'   For i As Integer = 0 To symbol_prices.Count - 1 
'    points(i) = New PointF(i, symbol_prices(i)) 
'   Next i 

'   ' Draw the points. 
'   Dim clr As Color = colors(symbol_num Mod colors.Length) 
'   Using thin_pen As New Pen(clr, 0) 
'    gr.DrawLines(thin_pen, points) 
'   End Using 

'   ' Draw the symbol's name. 
'   DrawSymbolName(gr, Symbols(symbol_num), _ 
'    symbol_prices(symbol_prices.Count - 1), clr) 
'  Next symbol_num 
' End Using 

' ' Display the result. 
' picGraph.Image = bm 
'End Sub 

' Draw the text at the specified location. 
'Private Sub DrawSymbolName(ByVal gr As Graphics, ByVal txt As String, ByVal y As Single, ByVal clr As Color) 
' ' See where the point is in PictureBox coordinates. 
' Dim old_transformation As Matrix = gr.Transform 
' Dim pt() As PointF = {New PointF(0, y)} 
' gr.Transform.TransformPoints(pt) 

' ' Reset the transformation. 
' gr.ResetTransform() 

' ' Draw the text. 
' Using small_font As New Font("Arial", 8) 
'  Using br As New SolidBrush(clr) 
'   gr.DrawString(txt, small_font, br, 0, pt(0).Y) 
'  End Using 
' End Using 

' ' Restore the original transformation. 
' gr.Transform = old_transformation 
'End Sub 

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

    End Sub 
End Class 

私も、私はJSONをデシリアライズしようとしていますし、私は結果にJSON文字列をダンプし、デシリアライザにいることを渡すと、次のエラーに

を取得していますGoogleFinanceItemクラスに

Imports Newtonsoft.Json 


Public Class GoogleFinanceItem 

Public Property id As String 
Public Property t As String 
Public Property e As String 
Public Property l As String 
<JsonProperty("l_fix")> 
Public Property price As String 
Public Property l_cur As String 
Public Property s As String 
Public Property ltt As String 
Public Property lt As String 
Public Property lt_dts As Date 
Public Property c As String 
Public Property c_fix As String 
Public Property cp As String 
Public Property cp_fix As String 
Public Property ccol As String 
Public Property pcls_fix As String 


End Class 

を持っています

Newtonsoft.Json.dllで 'Newtonsoft.Json.JsonSerializationException'の未処理の例外が発生しました

追加情報:現在のJSONオブジェクトを逆シリアル化できません(例:タイプを正しくデシリアライズするにはタイプにJSON配列([1,2,3]など)が必要なため、タイプ 'howto_net_graph_stock_history.GoogleFinanceItem []'に{{"name": "value"}}

このエラーを修正するには、JSON配列をJSON配列([1,2,3]など)に変更するか、デシリアライズされた型を通常の.NET型に変更します(整数などのプリミティブ型ではありません)。 JSONオブジェクトからデシリアライズできる配列やリストなどのコレクション型)。 JsonObjectAttributeを型に追加して、強制的にJSONオブジェクトから逆シリアル化することもできます。派手な形式の文字列だけではありません

enter image description here

+0

JSONをオブジェクトに逆シリアル化した方がずっと簡単です。 – TyCobb

+0

私はGoogleの逆シリアル化が簡単だと思われる。これを行うためには何をインポートしなければなりませんか?私はこれを試してみたい、他の方法でも比較を見たい – Edgar

答えて

3

。これはJSON文字列で、すべての情報に簡単にアクセスできるオブジェクトに解析または非直列化することができます。

まず、Newtonsoft's JSON parserを取得します。そして、データをキャプチャするクラス:

' see this link for the meaning of the other properties 
'https://www.quora.com/What-do-the-following-attributes-returned-in-a-JSON-array-from-the-Google-Finance-API-mean 
Public Class GoogleFinanceItem 
    Public Property id As String 
    <JsonProperty("t")> 
    Public Property Symbol As String 
    <JsonProperty("e")> 
    Public Property Index As String 
    <JsonProperty("l")> 
    Public Property LastTradePrice As Decimal 
    <JsonProperty("l_fix")> 
    Public Property LastPriceCurrency As Decimal 
    Public Property l_cur As String 
    Public Property s As String 
    Public Property ltt As String 
    Public Property lt As String 
    Public Property lt_dts As Date 
    <JsonProperty("c")> 
    Public Property Change As String 
    Public Property c_fix As String 
    Public Property cp As String 
    Public Property cp_fix As Decimal 
    Public Property ccol As String 
    Public Property pcls_fix As String 
End Class 

あなたは自動こうしてクラスを生成することができます

  1. コピーJSONクリップボード
  2. には、新しいクラスファイル
  3. を作成[編集]を選択します| |あなたはそれを持っていないのVisual Studioの多くの古いバージョンをお持ちの場合はクラス

としてJSONを貼り付け、あなたは、VBやC#クラスを作成するhttp://jsonutils.com/でロボットを使用することができます。

私はロボットが提案したクラスを少し変更しました。 a)それらはかなりgroodyのプロパティ名です。よりわかりやすいものや読みやすいものに変換するには、<JsonProperty("json name")>を使用して、JSON.NETに別のプロパティ名に逆シリアル化するよう伝えることができます。 b)数値をDecimalに変更したので、数学でも使用できます。

デシリアライズは簡単ですが、余分なクリーンアップ手順があります。Googleは自ら応答を使用するのではなく、APIを使用する方が望ましいと思われるので、先頭に「//」があります。これは、逆シリアル化される前にトリミングされる必要がある:

この場合
Dim jstr = GetWebResponse(url).Replace("//", "") 

Dim items As GoogleFinanceItem() = JsonConvert.DeserializeObject(Of GoogleFinanceItem())(jstr) 

それが一方の配列であるが、データのプロパティを介して利用できるようになります表示するために、プロパティグリッドを使用して

Console.Writeline(items(0).Ticker)) 

オブジェクトのプロパティ値:

enter image description here


今後のR eadersは、DGVのリストに複数の引用符を付けることができます。 APIの外で1回のリクエストで複数引用符を要求する方法があるかどうかは不明です。だから、ループを使用します。

Dim syms As String() = {"GOOG", "MSFT", "INTC"} 
GQuotes = New List(Of GoogleFinanceItem) 

Dim urlMask As String = "http://finance.google.com/finance/info?client=ig&q={0}" 
Dim url As String 

For Each s As String In syms 
    url = String.Format(urlMask, s) 
    Dim jstr As String = GetWebResponse(url).Replace("//", "") 
    Dim items = JsonConvert.DeserializeObject(Of GoogleFinanceItem())(jstr) 

    GQuotes.Add(items(0)) 
Next 

dgv1.DataSource = GQuotes 

リストが長い場合、時間の短すぎるであまりにも多くのリクエストを投稿しないようにする要求間で簡単に一時停止する必要があるかもしれません。

enter image description here

関連する問題