TMDbのAPIを利用してテレビドラマ情報を検索し、JSONをデシリアライズする練習

TMDbでは映画情報やテレビドラマの情報をAPIで公開しています。ユーザ登録するとAPIキーが発行されます。発行されたAPIキーをURLに埋め込んでリクエストすると、JSON形式で結果が返却されます。

WebAPIで取得できるJSON形式のデータを構造化する練習です。ツールはASP.NET(VB)を使用します。素人なので間違い、不適切な使用方法があるかもしれませんが、その時はご指摘、ご指導いただければと思います。


完成イメージ


ここではテレビドラマのタイトルと取得結果の言語を選択できるようにします。
10

テレビドラマのタイトルに今話題の walking dead、言語に英語してSearchをクリックします。
11

すると2つのWalking Dead がヒットし、その結果がGridViewとDataListに展開されました。
12

言語を日本語にすると日本語のあらすじ(overview)を取得できます。ただし、現時点ではTMDbには日本語情報がほとんど登録されていない状況なので、日本語で検索する意味はあまりないかもしれません。
13

なお、ウォーキング・デッドで検索してもヒットします。
14


到達目標

テレビドラマのタイトルを指定して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で、右側がそれをデシリアライズして構造化表示したもの00

図2:図1の構造を展開してみる
01

図3:TMDbAPIのドキュメント
02


VB.NETでのクラス定義

JSONの構造から下記のようにクラスを定義します。

Results of Search for TV
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


TMDbAPIへのリクエストとJSONのデシリアライズ

APIキー(api_key)は*で伏せています。定義済のTvResultsクラスをを第1引数、リクエストURLを第2引数にして、DeserializeJSON を呼び出します。

Call DeserializeJSON
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)

StreamReaderでJSONを文字列で取得し、取得した文字列をJavaScriptSerializerのDeserializeでTvResultsクラス定義に従い構造化します。

Request and Deserialize
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


ソース全文

TMDbTV.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="TMDbTV.aspx.vb" Inherits="TMDbTV" %>

<!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" />
&nbsp;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>


TMDbTV.aspx.vb
Imports System.Web.Script.Serialization
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


web.config
<?xml version="1.0"?>
<!--
   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>


関連記事

コメント

このブログの人気の投稿

ダブルクォーテーションで括られたCSVカ​ンマ区切りテキストファイルを SQL Server で Bulk Insert する方法

PowerShellでTSV/CSVの列を絞り込んで抽出し、(先頭/行末)からN行出力する

IKEAの鏡を壁に取り付ける