Skip to content

Instantly share code, notes, and snippets.

@furyutei
Last active August 22, 2026 15:21
Show Gist options
  • Select an option

  • Save furyutei/9233c71e4cadb1d2cf718f2ef2d57ea6 to your computer and use it in GitHub Desktop.

Select an option

Save furyutei/9233c71e4cadb1d2cf718f2ef2d57ea6 to your computer and use it in GitHub Desktop.
[PowerShell] 「超かぐや姫!おつかれさま本」の画像をダウンロードするスクリプト

[PowerShell] 「超かぐや姫!おつかれさま本」の画像をダウンロードするスクリプト

「260815_超かぐや姫おつかれさま本」の画像をダウンロードするためのPowerShellスクリプト。

V​​P​​​С​​F @CPK!@vpcf90 さんツイート(ポスト)を参考に、ほぼChatGPTに丸投げして書いてもらったもの。

使い方

  1. あらかじめ、*.ps1ファイルが実行できるようにPowerShellを管理者として実行した上で、

    Set-ExecutionPolicy RemoteSigned

    のようにして実行ポリシーを変更しておく。

  2. CPK_Otsukare_download.ps1の内容をコピーして、メモ帳などに貼り付け、「名前をつけて保存(A)」から 文字コードを『UTF-8 (BOM 付き)』にして "CPK_Otsukare_download.ps1"という名前で保存する。

  3. 2 で保存したフォルダーに移動して、PowerShellを起動し、CPK_Otsukare_download.ps1を実行すると、同じフォルダ内に画像が保存される……はず。

# ============================================================
# 文字コード設定
# ============================================================
[Console]::InputEncoding = [System.Text.UTF8Encoding]::new($false)
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)
$OutputEncoding = [System.Text.UTF8Encoding]::new($false)
# ============================================================
# Dropbox の PDF プレビューからページ画像を取得して PNG 保存する
#
# ・Dropbox のPDFプレビュー画面を Edge で読み込む
# ・HTML内からページ画像URLを取得する
# ・PDFの総ページ数を自動取得する
# ・各ページを指定倍率でダウンロードする
# ・横長画像なら見開きと判断して左右に分割する
# ・ページタイトルを出力ファイル名に使う
# ・PNG形式で連番保存する
# ============================================================
# ------------------------------------------------------------
# 設定
# ------------------------------------------------------------
$DropboxUrl = "https://dropbox.com/scl/fi/2dz2rnch41n0ym6svx2v1/260815_.pdf?rlkey=79hr9bq43shkosbwhe93003lu"
# Dropbox 側の最初のページ画像番号
$FirstPageIndex = 0
# ページ総数を取得できなかった場合のデフォルト値
$DefaultLastPageIndex = 44
# Dropbox の画像取得時の拡大率
$ScalePercent = 400
# ------------------------------------------------------------
# System.Drawing を読み込む
# ------------------------------------------------------------
Add-Type -AssemblyName System.Drawing
# ============================================================
# 1. Microsoft Edge の実行ファイルを取得
# ============================================================
# まず、現在起動中の Edge プロセスを探す
$edgeProcess = Get-Process msedge -ErrorAction SilentlyContinue |
Select-Object -First 1
if ($edgeProcess) {
# 起動中の Edge が見つかった場合
$edgePath = $edgeProcess.Path
}
else {
# 起動中の Edge が見つからなかった場合は
# 標準的なインストール先を使用
$edgePath = "${env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe"
}
# Edge 本体が存在するか確認
if (-not (Test-Path $edgePath)) {
throw "Microsoft Edge が見つかりませんでした: $edgePath"
}
Write-Host "Microsoft Edge:"
Write-Host " $edgePath"
# ============================================================
# 2. Edge をヘッドレス起動して Dropbox ページの DOM を取得
# ============================================================
Write-Host ""
Write-Host "Dropbox ページを読み込んでいます..."
$html = & $edgePath `
--headless `
--dump-dom `
$DropboxUrl |
Out-String
# ============================================================
# 3. PDF の総ページ数を取得
#
# 優先順位:
#
# 1. data-testid="page-count" 周辺
# 2. HTML全文の "数字 / 数字"
# 3. デフォルト値
# ============================================================
$LastPageIndex = $null
$totalPages = $null
# ------------------------------------------------------------
# 3-1. page-count 周辺から探す
# ------------------------------------------------------------
$pageCountMatch = [regex]::Match(
$html,
'(?is)data-testid\s*=\s*["'']page-count["''].{0,3000}?(\d+)\s*/\s*(\d+)'
)
if ($pageCountMatch.Success) {
$currentPage = [int]$pageCountMatch.Groups[1].Value
$totalPages = [int]$pageCountMatch.Groups[2].Value
$LastPageIndex = $totalPages - 1
Write-Host ""
Write-Host "ページ数を page-count から取得しました。"
Write-Host " 現在ページ: $currentPage"
Write-Host " 総ページ数: $totalPages"
}
# ------------------------------------------------------------
# 3-2. page-count で見つからなければ、
# HTML全文から "数字 / 数字" を探す
# ------------------------------------------------------------
if ($null -eq $LastPageIndex) {
# HTMLタグを簡易的に除去してテキスト化
$pageText = $html -replace '<[^>]+>', ' '
# HTMLエンティティをデコード
$pageText = [System.Net.WebUtility]::HtmlDecode(
$pageText
)
# 例:
# 1 / 45
# 1/45
# 12 / 100
#
# のような表記をすべて探す
$pageMatches = [regex]::Matches(
$pageText,
'\b(\d+)\s*/\s*(\d+)\b'
)
if ($pageMatches.Count -gt 0) {
# 複数候補がある場合は、
# 総ページ数が最大のものを採用
$pageInfo = $pageMatches |
ForEach-Object {
[PSCustomObject]@{
Current = [int]$_.Groups[1].Value
Total = [int]$_.Groups[2].Value
}
} |
Sort-Object Total -Descending |
Select-Object -First 1
$totalPages = $pageInfo.Total
$LastPageIndex = $totalPages - 1
Write-Host ""
Write-Host "ページ数をHTML全文から取得しました。"
Write-Host " 現在ページ: $($pageInfo.Current)"
Write-Host " 総ページ数: $totalPages"
}
}
# ------------------------------------------------------------
# 3-3. それでも見つからなければデフォルト値を使用
# ------------------------------------------------------------
if ($null -eq $LastPageIndex) {
$LastPageIndex = $DefaultLastPageIndex
$totalPages = $LastPageIndex + 1
Write-Warning "PDFの総ページ数を取得できませんでした。デフォルト値を使用します。"
Write-Warning "LastPageIndex = $LastPageIndex"
}
Write-Host ""
Write-Host "取得対象:"
Write-Host " Dropbox画像 $FirstPageIndex ~ $LastPageIndex"
Write-Host " 想定画像数: $($LastPageIndex - $FirstPageIndex + 1)"
# ============================================================
# 4. HTML の <title> から出力ファイル名を作成
# ============================================================
if ($html -match '(?is)<title>(.*?)</title>') {
$documentTitle = $Matches[1]
# HTMLエンティティを通常の文字に戻す
$documentTitle = [System.Net.WebUtility]::HtmlDecode(
$documentTitle
)
# 前後の空白を除去
$documentTitle = $documentTitle.Trim()
# 末尾の .pdf を取り除く
$documentTitle = $documentTitle -replace '(?i)\.pdf$', ''
# Windows のファイル名に使えない文字を "_" に置換
$invalidChars = [System.IO.Path]::GetInvalidFileNameChars()
foreach ($char in $invalidChars) {
$documentTitle = $documentTitle.Replace($char, '_')
}
# 拡大率を末尾に付ける
$OutputPrefix = "$documentTitle($ScalePercent)"
}
else {
throw "ページの <title> を取得できませんでした。"
}
Write-Host ""
Write-Host "出力ファイル名:"
Write-Host " $OutputPrefix"
# ============================================================
# 5. HTML からページ画像URLのベース部分を探す
# ============================================================
# 元のワンライナーと同様に、
# "htt" から "ge=" までの最初の文字列を探す。
#
# Dropbox内部で使われているページ画像URLの
# page= の直前までを取得することを意図している。
if ($html -notmatch 'https:.+?page=') {
throw "ページ画像のURLをHTML内から見つけられませんでした。Dropbox側の仕様が変更された可能性があります。"
}
$baseImageUrl = $Matches[0]
# HTML中の &amp; を通常の & に戻す
$baseImageUrl = $baseImageUrl -replace 'amp;', ''
Write-Host ""
Write-Host "画像URLのベース部分:"
Write-Host " $baseImageUrl"
# ============================================================
# 6. 各ページ画像をダウンロードして処理
# ============================================================
$outputPageNumber = 0
foreach ($pageIndex in $FirstPageIndex..$LastPageIndex) {
# --------------------------------------------------------
# ページ画像URLを作成
# --------------------------------------------------------
$imageUrl =
$baseImageUrl +
$pageIndex +
"&scale_percent=$ScalePercent"
Write-Host ""
Write-Host "取得中: Dropbox画像 $pageIndex"
Write-Host " $imageUrl"
# --------------------------------------------------------
# ページ画像をダウンロード
# --------------------------------------------------------
$response = Invoke-WebRequest `
-Uri $imageUrl `
-UseBasicParsing
# --------------------------------------------------------
# ダウンロードした画像をメモリ上で Bitmap として読み込む
# --------------------------------------------------------
$memoryStream = [System.IO.MemoryStream]::new(
$response.Content
)
$image = [System.Drawing.Bitmap]::new(
$memoryStream
)
try {
Write-Host " 画像サイズ: $($image.Width) x $($image.Height)"
# ====================================================
# 7. 単ページか見開きかを判定
#
# 横長:
# Width > Height
# → 見開きと判断して左右に分割
#
# 縦長または正方形:
# Width <= Height
# → 単ページとしてそのまま保存
# ====================================================
if ($image.Width -gt $image.Height) {
Write-Host " 判定: 横長 → 見開き"
# 画像幅が奇数でも1px欠けないようにする
$leftWidth = [int][Math]::Floor(
$image.Width / 2
)
$rightWidth =
$image.Width - $leftWidth
# 左ページと右ページの切り抜き範囲
$regions = @(
@{
X = 0
Width = $leftWidth
},
@{
X = $leftWidth
Width = $rightWidth
}
)
}
else {
Write-Host " 判定: 縦長または正方形 → 単ページ"
# 画像全体をそのまま使用
$regions = @(
@{
X = 0
Width = $image.Width
}
)
}
# ====================================================
# 8. 指定範囲を切り抜いて PNG 保存
# ====================================================
foreach ($region in $regions) {
$outputPageNumber++
# ------------------------------------------------
# 切り抜き範囲を作成
# ------------------------------------------------
$rectangle = [System.Drawing.Rectangle]::new(
$region.X,
0,
$region.Width,
$image.Height
)
# ------------------------------------------------
# 画像を切り抜く
# ------------------------------------------------
$croppedImage = $image.Clone(
$rectangle,
$image.PixelFormat
)
try {
# --------------------------------------------
# 出力ファイル名
#
# 例:
# 260815_超かぐや姫おつかれさま本(400)_001.png
# 260815_超かぐや姫おつかれさま本(400)_002.png
# --------------------------------------------
$fileName = "{0}_{1:D3}.png" -f `
$OutputPrefix,
$outputPageNumber
# --------------------------------------------
# PNGとして保存
# --------------------------------------------
$croppedImage.Save(
$fileName,
[System.Drawing.Imaging.ImageFormat]::Png
)
Write-Host " 保存: $fileName"
}
finally {
# 切り抜き画像を解放
$croppedImage.Dispose()
}
}
}
finally {
# 元画像とメモリストリームを確実に解放
$image.Dispose()
$memoryStream.Dispose()
}
}
# ============================================================
# 完了
# ============================================================
Write-Host ""
Write-Host "完了しました。"
Write-Host "Dropbox画像数: $($LastPageIndex - $FirstPageIndex + 1)"
Write-Host "保存したPNGページ数: $outputPageNumber"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment