Qiita API v2をPowerShellから実行してみる
の記事でPowerShell
でQiita API v2
を実行して、記事の一覧を取得してみましたが。
今回はスクリプトに引数としてアクセストークンを渡す事により、認証したユーザの公開記事と限定公開記事を一括でダウンロードしてみます。
なお下書きについては、下書きを取得できるAPIが無いようなので非対応。
APIで取得した内容から記事ごとにフォルダを作り、記事本文と画像をダウンロードしています。
例としては下記画像のような感じとなっており。
フォルダの中には、body.md
と本文で利用されている画像が保存されまいます。
Copy-AuthQiitaItems.ps1
# !/usr/bin/env pwsh
<#
.SYNOPSIS
qiita アクセストークン認証ユーザの記事をダウンロードするやつ
.DESCRIPTION
qiitaのアクセストークン認証したユーザの記事一覧をダウンロードします。
ダウンロード対象は公開記事と限定公開の記事のみ。
下書きについては、下書きを取得できるAPIが存在しないようなので対象外。
qiitaのapi v2を利用しているので利用制限に引っかかるととまります
https://qiita.com/api/v2/docs#利用制限
.EXAMPLE
PS C:\> ./Copy-AuthQiitaItems.ps1 -Token <<access token>>
PS C:\> "<<Token>>" | ./Copy-AuthQiitaItems.ps1
.INPUTS
System.String
.OUTPUTS
System.Collections.ArrayList
.NOTES
None
# >
param (
[Parameter(ValueFromPipeline = $True, Mandatory = $True)]
[String]$Token
)
PROCESS {
Set-StrictMode -Version Latest
$ErrorActionPreference = "stop"
# 認証用
$headers = @{Authorization = "Bearer $Token" }
# 一時配列
$workArray = New-Object System.Collections.ArrayList
# 1ページ目取得
$uri = 'https://qiita.com/api/v2/authenticated_user/items?page=1&per_page=100'
$1stResponse = Invoke-WebRequest -Headers $headers -Uri $uri
$workArray += ($1stResponse | Select-Object -ExpandProperty Content | ConvertFrom-Json ) | Select-Object created_at, url, title, updated_at, private , tags , body
#ページ処理
#レスポンスヘッダから記事数を取得
$totalCount = ([int[]]$1stResponse.Headers["Total-Count"])[0]
# ページ数を計算
$maxPage = [Math]::Ceiling($totalCount / 100)
# 2ページ以降があったら取得
for ($nowPage = 2; $nowPage -le $maxPage; $nowPage++) {
$uri = 'https://qiita.com/api/v2/authenticated_user/items?page={1}&per_page=100' -f $userId, $nowPage
$workArray += $(Invoke-WebRequest -Headers $headers -Uri $uri | Select-Object -ExpandProperty Content | ConvertFrom-Json) `
| Select-Object created_at, url, title, updated_at, private
}
# 各記事と画像をダウンロード
foreach ($workObj in $workArray) {
# タイトル名で記事ごとにフォルダ分け
$downloadFolderName = $workObj.title
# ファイルに利用できない文字を削除
[RegEx]::Replace($downloadFolderName, "[{0}]" -f [RegEx]::Escape([string][System.IO.Path]::GetInvalidFileNameChars()) , '')
# 保存用フォルダパス
$downloadFolderPath = Join-Path -Path $PsScriptRoot -ChildPath $downloadFolderName
# フォルダ生成
New-Item -ItemType Directory -Path $downloadFolderPath -Force
# body出力用パス
$mdPath = Join-Path -Path $downloadFolderPath -ChildPath "body.md"
# bodyをutf8で保存
$workObj.body | Out-File -Force $mdPath -Encoding utf8
# imageをダウンロードして保存
# bodyからurlを抽出
$imageUrls = $workObj.body | Select-String '\!\[.*\]\((?<url>.*)\)' -AllMatches | ForEach-Object Matches | ForEach-Object groups | Where-Object name -EQ url | ForEach-Object value
foreach ($imageUrl in $ImageUrls) {
$imageName = Split-Path $imageUrl -Leaf
$imagePath = Join-Path -Path $downloadFolderPath -ChildPath $imageName
Invoke-WebRequest $imageUrl -OutFile $imagePath
}
}
$workArray | Select-Object created_at, url, title, updated_at, private , tags | ConvertTo-json -Depth 3 | out-file -path $(Join-Path -Path $PsScriptRoot -ChildPath index.json) -Encoding utf8
}
やっていること
- APIから取得したtitleからファイル利用できない文字を削除してフォルダ作成
- APIから取得できたbodyから画像ファイルのURLを抽出してダウンロード
- APIから取得できたbodyをutf8でbody.mdとしてダウンロード
- APIから取得できたメタ情報をindex.jsonとしてダウンロード
APIを実行して、ファイル保存しているくらいです。