TMDbのAPIを利用してテレビドラマ情報を検索し、JSONをデシリアライズする練習
TMDbでは映画情報やテレビドラマの情報をAPIで公開しています。ユーザ登録するとAPIキーが発行されます。発行されたAPIキーをURLに埋め込んでリクエストすると、JSON形式で結果が返却されます。
WebAPIで取得できるJSON形式のデータを構造化する練習です。ツールはASP.NET(VB)を使用します。素人なので間違い、不適切な使用方法があるかもしれませんが、その時はご指摘、ご指導いただければと思います。
完成イメージ
ここではテレビドラマのタイトルと取得結果の言語を選択できるようにします。
テレビドラマのタイトルに今話題の walking dead、言語に英語してSearchをクリックします。
すると2つのWalking Dead がヒットし、その結果がGridViewとDataListに展開されました。
言語を日本語にすると日本語のあらすじ(overview)を取得できます。ただし、現時点ではTMDbには日本語情報がほとんど登録されていない状況なので、日本語で検索する意味はあまりないかもしれません。
到達目標
テレビドラマのタイトルを指定してTMDbを検索します。検索結果はシリアライズされたJSON形式の1行テキストで返却されます。これを定義済のオブジェクトへ展開し、GridViewやDataListに展開します。
TMDbのSearchコマンド
TMDbAPIのSearchコマンドのTVを使用します。
ウォーキングデッド(walking dead)を検索するリクエスト
https://api.themoviedb.org/3/search/tv?api_key=APIキーの値&query=walkig dead
返却されるJSON及びその構造
JSONをオンラインでシリアライズ・デシリアライズしてくれる便利なサイトがあるので、それを使うか、TMDbのAPIのドキュメントをみてJSONの構造を調べます。
図1、図2は walking dead で検索した結果取得したJSONです。
図1:左側が返却されたJSONで、右側がそれをデシリアライズして構造化表示したもの
VB.NETでのクラス定義
JSONの構造から下記のようにクラスを定義します。
Public Property page() As Integer
Public Property results() As List(Of TvResult)
Public Property total_pages() As Integer
Public Property total_results() As Integer
End Class
Public Class TvResult
Public Property backdrop_path() As String
Public Property first_air_date() As String
Public Property genre_ids() As List(Of Integer)
Public Property id() As Integer
Public Property original_language() As String
Public Property original_name() As String
Public Property overview() As String
Public Property origin_country() As List(Of String)
Public Property poster_path() As String
Public Property popularity() As Double
Public Property name() As String
Public Property vote_average() As Double
Public Property vote_count() As Integer
End Class
TMDbAPIへのリクエストとJSONのデシリアライズ
APIキー(api_key)は*で伏せています。定義済のTvResultsクラスをを第1引数、リクエストURLを第2引数にして、DeserializeJSON を呼び出します。
Dim TvResults As New TvResults()
TvResults = DeserializeJSON(Of TvResults)(strURL)
StreamReaderでJSONを文字列で取得し、取得した文字列をJavaScriptSerializerのDeserializeでTvResultsクラス定義に従い構造化します。
Dim objResults As T
Dim objSrializer As JavaScriptSerializer = New JavaScriptSerializer()
Dim request = TryCast(System.Net.WebRequest.Create(TargetURL), System.Net.HttpWebRequest)
request.Method = "GET"
request.Accept = "application/json"
request.ContentLength = 0
Dim responseContent As String = ""
Try
Using response = TryCast(request.GetResponse(), System.Net.HttpWebResponse)
Using reader = New System.IO.StreamReader(response.GetResponseStream())
responseContent = reader.ReadToEnd()
objResults = objSrializer.Deserialize(Of T)(responseContent)
End Using
End Using
Catch ex As WebException
LabelResult.Text = ex.Message
objResults = Nothing
End Try
Return objResults
End Function
ソース全文
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBoxTitle" runat="server"></asp:TextBox>
<asp:Button ID="ButtonSearch" runat="server" Text="Search" />
Language:<asp:DropDownList ID="DropDownListLanguage" runat="server">
<asp:ListItem Selected="True" Value="en">English</asp:ListItem>
<asp:ListItem Value="ja">Japanese</asp:ListItem>
</asp:DropDownList>
<asp:Label ID="LabelResult" runat="server"></asp:Label>
<br />
<br />
<asp:GridView ID="GridViewTVID" runat="server">
</asp:GridView>
<br />
<asp:DataList ID="DataListTVID" runat="server" RepeatColumns="10" RepeatDirection="Horizontal">
<ItemTemplate>
<div>
<asp:Image ID="ImageTVIDPoster" runat="server" ImageUrl='<%# eval("TVIDPosterPathW150") %>' />
<br />
TMDbTVID:<asp:Label ID="LabelTVID" runat="server" Text='<%# eval("TMDbTVID") %>'></asp:Label>
<br />
<asp:Label ID="Labeloriginal_name" runat="server" Text='<%# eval("original_name") %>'></asp:Label>
<br />
<asp:Label ID="Labelfirst_air_date" runat="server" Text='<%# eval("first_air_date") %>'></asp:Label>
<br />
<asp:Label ID="Labelname" runat="server" Text='<%# eval("name") %>'></asp:Label>
</div>
<asp:Image ID="ImageTVIDBackdrop" runat="server" ImageUrl='<%# eval("TVIDBackdropPathW150") %>' />
<asp:Label ID="LabelPosterW300" runat="server" Text='<%# eval("TVIDPosterPathW300") %>' Visible="False"></asp:Label>
<asp:Label ID="LabelBackdropW600" runat="server" Text='<%# eval("TVIDBackdropPathW600") %>' Visible="False"></asp:Label>
<br />
<asp:Label ID="Labeloverview" runat="server" Text='<%# eval("overview") %>'></asp:Label>
<br />
<asp:Button ID="ButtonSelect" runat="server" Text="" />
</ItemTemplate>
</asp:DataList>
</div>
</form>
</body>
</html>
Imports System.Net
Imports System.Data
Partial Class TMDbTV
Inherits System.Web.UI.Page
Public Class TvResults
Public Property page() As Integer
Public Property results() As List(Of TvResult)
Public Property total_pages() As Integer
Public Property total_results() As Integer
End Class
Public Class TvResult
Public Property backdrop_path() As String
Public Property first_air_date() As String
Public Property genre_ids() As List(Of Integer)
Public Property id() As Integer
Public Property original_language() As String
Public Property original_name() As String
Public Property overview() As String
Public Property origin_country() As List(Of String)
Public Property poster_path() As String
Public Property popularity() As Double
Public Property name() As String
Public Property vote_average() As Double
Public Property vote_count() As Integer
End Class
Protected Sub ButtonSearch_Click(sender As Object, e As EventArgs) Handles ButtonSearch.Click
Dim ImageURLOriginal As String = ConfigurationManager.AppSettings("ImageURLOriginal")
Dim ImageURLW600 As String = ConfigurationManager.AppSettings("ImageURLW600")
Dim ImageURLW300 As String = ConfigurationManager.AppSettings("ImageURLW300")
Dim ImageURLW150 As String = ConfigurationManager.AppSettings("ImageURLW150")
Dim strURL As String = "https://api.themoviedb.org/3/search/tv?api_key=***&query=" + TextBoxTitle.Text + "&language=" + DropDownListLanguage.SelectedValue
Dim TvResults As New TvResults()
TvResults = DeserializeJSON(Of TvResults)(strURL)
If TvResults.total_results > 0 Then
Dim tableTVID As New DataTable
tableTVID.Columns.Add("TMDbTVID")
tableTVID.Columns.Add("backdrop_path")
tableTVID.Columns.Add("original_name")
tableTVID.Columns.Add("first_air_date")
tableTVID.Columns.Add("poster_path")
tableTVID.Columns.Add("popularity")
tableTVID.Columns.Add("name")
tableTVID.Columns.Add("vote_average")
tableTVID.Columns.Add("vote_count")
tableTVID.Columns.Add("overview")
tableTVID.Columns.Add("TVIDPosterPathW150")
tableTVID.Columns.Add("TVIDBackdropPathW150")
tableTVID.Columns.Add("TVIDPosterPathW300")
tableTVID.Columns.Add("TVIDBackdropPathW600")
For Each item In TvResults.results
Dim rowTVID = tableTVID.NewRow()
rowTVID("TMDbTVID") = item.id
rowTVID("backdrop_path") = item.backdrop_path
rowTVID("original_name") = item.original_name
rowTVID("first_air_date") = item.first_air_date
rowTVID("poster_path") = item.poster_path
rowTVID("popularity") = item.popularity
rowTVID("name") = item.name
rowTVID("vote_average") = item.vote_average
rowTVID("vote_count") = item.vote_count
rowTVID("overview") = item.overview
rowTVID("TVIDPosterPathW150") = ImageURLW150 + item.poster_path
rowTVID("TVIDBackdropPathW150") = ImageURLW150 + item.backdrop_path
rowTVID("TVIDPosterPathW300") = ImageURLW300 + item.poster_path
rowTVID("TVIDBackdropPathW600") = ImageURLW600 + item.backdrop_path
tableTVID.Rows.Add(rowTVID)
Next
GridViewTVID.DataSource = tableTVID
GridViewTVID.DataBind()
DataListTVID.DataSource = tableTVID
DataListTVID.DataBind()
End If
End Sub
Public Function DeserializeJSON(Of T)(ByVal TargetURL As String) As T
Dim objResults As T
Dim objSrializer As JavaScriptSerializer = New JavaScriptSerializer()
Dim request = TryCast(System.Net.WebRequest.Create(TargetURL), System.Net.HttpWebRequest)
request.Method = "GET"
request.Accept = "application/json"
request.ContentLength = 0
Dim responseContent As String = ""
Try
Using response = TryCast(request.GetResponse(), System.Net.HttpWebResponse)
Using reader = New System.IO.StreamReader(response.GetResponseStream())
responseContent = reader.ReadToEnd()
objResults = objSrializer.Deserialize(Of T)(responseContent)
End Using
End Using
Catch ex As WebException
LabelResult.Text = ex.Message
objResults = Nothing
End Try
Return objResults
End Function
Protected Sub GridViewTVID_RowCreated(sender As Object, e As GridViewRowEventArgs) Handles GridViewTVID.RowCreated
If e.Row.RowType = DataControlRowType.DataRow _
OrElse e.Row.RowType = DataControlRowType.Header Then
e.Row.Cells(9).Visible = False
End If
End Sub
End Class
<!--
ASP.NET
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<connectionStrings>
<add name="TESTConnectionString" connectionString="Data Source=SN78SH7;Initial Catalog=TEST;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5">
<assemblies>
<add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
<add assembly="System.Web.Extensions.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
<httpRuntime targetFramework="4.5"/>
</system.web>
<appSettings>
<add key="ImageURL" value="https://image.tmdb.org/t/p/w150" />
<add key="ImageURLW150" value="https://image.tmdb.org/t/p/w150" />
<add key="ImageURLW300" value="https://image.tmdb.org/t/p/w300" />
<add key="ImageURLW600" value="https://image.tmdb.org/t/p/w600" />
<add key="ImageURLW1280" value="https://image.tmdb.org/t/p/w1280" />
<add key="ImageURLOriginal" value="https://image.tmdb.org/t/p/original" />
<add key="ImageTMDbPosterFolder" value="D:\TMDbPoster"/>
<add key="Image2FileFolder" value="D:\Binary2ImagePosters"/>
</appSettings>
</configuration>
コメント
コメントを投稿