YAS's VB.NET Tips
 
VB.NET Tips
VB.NET Tips >> 記事詳細

2018/09/04

ぷりんときっずダウンローダーVer.1.0

| by:YAS
 ぷりんときっずの無料プリントをよく利用させていただいている。フォントが丸文字のプリントもあったりするが,わざわざ教科書体で作り直してくださったものもあり,ありがたく活用させていただいている。
 まとめてダウンロードしたいプリントも多いのだが,一括ダウンロードはできないようなので,専用のダウンローダーを作成してみる。
 あまり負荷をかけるのもよくないとは思うが,かなり高速なレスポンスのサーバーのようなので,個人的にダウンローダーを作成して使う分には問題なさそうだと思っている。
 まずは,1ページにまとめられているPDFのプリントをすべてダウンロードしてみる。
 chromeでPDFのリンクを右クリック→検証で,デベロッパーツールでHTMLを確認すると,PDFのダウンロードページのPDFへのリンク部分は左のようになっている。
 PDFファイルへのリンクは,id="topic"のdiv要素を検索し,その中のa要素を検索して取得することにする。

※id="easy"のdiv要素内に「簡単」レベルのプリントが,id="normal"のdiv要素内に「普通」レベルのプリントが,id="hard"のdiv要素内に「難しい」レベルのプリントが格納されている。


 1つ1つのPDFファイルへのリンクは下のようなHTMLになっている。ファイル名からプリントを探しやすくするために,a要素内のp要素のInnerTextをファイル名として保存する。


 プリントの分類をわかりやすくするために,ダウンロードしたPDFフィアルを格納するフォルダは,下のパンくずリストをフォルダ名にする。


 パンくずリストは,id="pan-nav"のdiv要素を取得し,その中のspan要素のInnerTextから取得する。



 下のコードをフォームのコードにコピー・貼り付けをすれば動作します。
Option Explicit On
Option Strict On

Imports System.IO
Imports Microsoft.Win32

Public Class Form1

    
Private ToolStrip As New ToolStrip
    
Private WithEvents tsbDownload As New ToolStripButton With {.Text = "ダウンロード"}
    
Private StatusStrip As New StatusStrip
    
Private WithEvents tspProgress As New ToolStripProgressBar
    
Private tslStatus As New ToolStripLabel
    
Private WithEvents WebBrowser As New WebBrowser With {.Dock = DockStyle.Fill}
    
Private baseUrl As New Uri("https://print-kids.net/")

    
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        
Me.Text = "ぷりんときっずダウンローダー"
        
Me.Size = New Size(1024, 678)
        BrowserEmulation.CreateRenderingModeRegkey(BrowserEmulation.Emulation.IE11Edge)
        
Me.WebBrowser.ScriptErrorsSuppressed = True
        
Me.ToolStrip.Items.Add(tsbDownload)
        
Me.StatusStrip.Items.AddRange({tspProgress, tslStatus})
        
Me.Controls.AddRange({Me.ToolStrip, Me.WebBrowser, Me.StatusStrip})
        
Me.WebBrowser.Navigate(baseUrl)
    
End Sub

    
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        BrowserEmulation.DeleteRenderingModeRegkey()
    
End Sub

    
Private Sub tsbDownload_Click(sender As Object, e As EventArgs) Handles tsbDownload.Click
        downloadPdfs(
Me.WebBrowser.Url)
    
End Sub

    
Private Sub downloadPdfs(url As Uri)
        
Dim tempWebBrowser As New WebBrowser
        tempWebBrowser.ScriptErrorsSuppressed = 
True
        
AddHandler tempWebBrowser.DocumentCompleted, AddressOf WebBrowser_DocumentCompleted
        tempWebBrowser.Navigate(url)
    
End Sub

    
Private Sub WebBrowser_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
        
Dim Browser As WebBrowser = DirectCast(sender, WebBrowser)
        
If e.Url.Equals(Browser.Url) Then
            
'PDFファイルのリンクを取得
            
Dim pdfLinks = Browser.Document.GetElementById("topic").GetElementsByTagName("a").Cast(Of HtmlElement) _
                .Select(
Function(anchorTag) New With {.AnchorElement = anchorTag, .Uri = New Uri(anchorTag.GetAttribute("href"))}) _
                .Where(
Function(anchorTag) baseUrl.IsBaseOf(anchorTag.Uri) AndAlso Path.GetExtension(anchorTag.Uri.AbsoluteUri).ToLower = ".pdf") _
                .Select(
Function(anchorTag) New With {anchorTag.Uri, .Text = anchorTag.AnchorElement.GetElementsByTagName("p")(0).InnerText})
            
'パンなびリストを取得
            
Dim downloadDir = Browser.Document.GetElementById("pan-nav").GetElementsByTagName("span").Cast(Of HtmlElement) _
                .Select(
Function(spanTag) spanTag.InnerText) _
                .Aggregate(
String.Empty, Function(result As String, title As String) Path.Combine(result, title))
            
'ダウンロード先フォルダ作成
            downloadDir = Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, downloadDir)
            
If Not Directory.Exists(downloadDir) Then
                My.Computer.FileSystem.CreateDirectory(Path.Combine(downloadDir))
            
End If
            
'PDFファイルをダウンロード
            
Dim Progress As Integer = 0
            
Me.tspProgress.Maximum = pdfLinks.Count
            
Me.tspProgress.Value = Progress
            
Me.tslStatus.Text = ""
            
Me.StatusStrip.Refresh()
            
For Each pdfLink In pdfLinks
                
Dim DownloadFileName As String = Path.Combine(downloadDir, pdfLink.Text.Replace(" """) & ".pdf")
                
Dim DownloadUrl As String = Path.GetFileName(pdfLink.Uri.AbsoluteUri)
                
Dim Status As String = " スキップ"
                
If Not File.Exists(DownloadFileName) Then
                    My.Computer.Network.DownloadFile(pdfLink.Uri, DownloadFileName)
                    Status = 
" ダウンロード中..."
                
End If
                
Me.tspProgress.Value = Progress
                
Me.tslStatus.Text = Progress + 1 & "/" & Me.tspProgress.Maximum & " " & DownloadUrl & Status
                
Me.StatusStrip.Refresh()
                Progress += 1
            
Next
            
Me.tspProgress.Value = Me.tspProgress.Maximum
            
Me.tslStatus.Text = "ダウンロード完了"
            
Me.StatusStrip.Refresh()
            Browser.Dispose()
        
End If
    
End Sub

End Class

Public Class BrowserEmulation

    
Public Enum Emulation
        IE11Edge = 11001
        IE11 = 11000
        IE10Std = 10001
        IE10 = 10000
        IE9Std = 9999
        IE9 = 9000
        IE8Std = 8888
        IE8 = 8000
        IE7 = 7000
    
End Enum

    
Private Const FEATURE_BROWSER_EMULATION As String = "Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION"

    
Public Shared Sub CreateRenderingModeRegkey(EmulationMode As Emulation)
        
Using Regkey As RegistryKey = Registry.CurrentUser.CreateSubKey(FEATURE_BROWSER_EMULATION)
            Regkey.SetValue(GetReleaseBuildName, EmulationMode, RegistryValueKind.DWord)
            Regkey.SetValue(GetDebugBuildName, EmulationMode, RegistryValueKind.DWord)
        
End Using
    
End Sub

    
Public Shared Sub DeleteRenderingModeRegkey()
        
Using Regkey As RegistryKey = Registry.CurrentUser.CreateSubKey(FEATURE_BROWSER_EMULATION)
            Regkey.DeleteValue(GetReleaseBuildName)
            Regkey.DeleteValue(GetDebugBuildName)
        
End Using
    
End Sub

    
Private Shared Function GetReleaseBuildName() As String
        
Return Path.GetFileName(Application.ExecutablePath)
    
End Function

    
Private Shared Function GetDebugBuildName() As String
        
Return GetReleaseBuildName.Replace(".exe"".svhost.exe")
    
End Function

End Class

22:23 | コメント(0)
メニュー