VB.NetでRadikoの週間番組表を取得してみる
Radikoの週間番組表は
http://radiko.jp/v2/api/program/station/weekly?station_id=[RadikoStationId]
で取得できるらしいので
HtmlAgilityPackを使ってみた
準備
プロジェクトでHtmlAgilityPackを使えるようにする
PM> Install-Package HtmlAgilityPack
週間番組表を扱うコードを書いてみる
RadikoProgram.vb
''' <summary>
''' Radikoの週間番組表を取得するUrl
''' </summary>
Dim RadikoProgramsBaseUrl = "http://radiko.jp/v2/api/program/station/weekly?station_id={0}"
''' <summary>
''' Radikoの番組データ
''' </summary>
Public Class Program
Property title As String
Property sub_title As String
Property desc As String
Property info As String
Property Start As DateTime
Property Duration As Integer
End Class
''' <summary>
''' Radikoの週間番組表
''' </summary>
Property Programs As List(Of Program)
''' <summary>
''' 番組表が取得が終わったEvent
''' </summary>
Event Programs_GetCompleted()
Public Sub New()
Programs = New List(Of Program)
End Sub
Public Async Sub GetPrograms(RadikoStationId As String)
Dim requestUri As String = String.Format(RadikoProgramsBaseUrl, RadikoStationId)
Dim Response = Await RadikoPrograms(requestUri)
Dim htmlDoc01 = New HtmlAgilityPack.HtmlDocument()
htmlDoc01.LoadHtml(Response)
Dim WeeklyPrograms = htmlDoc01.
DocumentNode.
SelectNodes("/radiko[1]/stations[1]/station[1]/scd[1]/progs").ToList
For Each DailyPrograms In WeeklyPrograms
Dim htmlDoc02 = New HtmlAgilityPack.HtmlDocument()
htmlDoc02.LoadHtml(DailyPrograms.InnerHtml)
Programs.AddRange(
htmlDoc02.
DocumentNode.
SelectNodes("/prog").
Select(Function(x) New Program With {
.title = x.ChildNodes.Item("title").InnerText,
.sub_title = x.ChildNodes.Item("sub_title").InnerText,
.desc = RemoveHTMLTag(x.ChildNodes.Item("desc").InnerText),
.info = RemoveHTMLTag(x.ChildNodes.Item("info").InnerText),
.Start = ToDateTime(x.Attributes("ft").Value),
.Duration = ToDuration(x.Attributes("dur").Value)
}).ToList)
Next
RaiseEvent Programs_GetCompleted()
End Sub
Private Async Function RadikoPrograms(requestUri As String) As Task(Of String)
Dim client As Net.Http.HttpClient = New Net.Http.HttpClient()
Dim getStringTask As Task(Of String) = client.GetStringAsync(requestUri)
Dim urlContents As String = Await getStringTask
Return urlContents
End Function
# Region "データの加工処理"
Private Function RemoveHTMLTag(args As String) As String
Dim RemovePattern As String = "<.*?>"
Return System.Text.RegularExpressions.Regex.Replace(args, RemovePattern, String.Empty)
End Function
Private Function ToDateTime(args As String) As DateTime
'20150101125959 -> 2015/01/01 12:59:59
Dim year = args.Substring(0, 4)
Dim month = args.Substring(4, 2)
Dim day = args.Substring(6, 2)
Dim hour = args.Substring(8, 2)
Dim minute = args.Substring(10, 2)
Return New DateTime(year, month, day, hour, minute, 0)
End Function
Private Function ToDuration(args As String) As Integer
Dim sec As Integer
If Integer.TryParse(args, sec) Then
Return sec / 60
Else
Return 0
End If
End Function
# End Region
書いたコードを使ってみる
終わった番組が表示されても仕方ないので、現在時刻以降の番組をDataGridに表示してみる
Radiko.vb
Dim RadikoProgram As New RadikoProgram
AddHandler RadikoProgram.Programs_GetCompleted, Sub()
DataGrid.ItemsSource = RadikoProgram.Programs.Where(Function(x) x.Start > System.DateTime.Now)
End Sub
Dim StationID = "QRR"
RadikoProgram.GetPrograms(RadikoStationId)
DataGridのItemsSourceに突っ込むだけでそれらしくなるWPFは便利