良いサイトを見つけたのだが、なにせページ数が膨大で、手動でコピペする案件ではなかったため、自動でエイヤとできないものかと模索した記録を残しておく。


検索では、どうやらwgetなるものを使えばいいということだけは分かったのだが、あいにくLinuxではなくWindowsユーザーなので、環境を整えるところから始まった。

wget導入

まずこのサイトからwgetを落とす。

Wget for Windows

全部使う訳ではなさそうだったが、自分にはよくわからないのでとりあえずComplete packageにした。任意のフォルダに保存。

hogehoge/wget/bin のパスをメモっておく。

タスクバーの窓アイコンを右クリックし、Power Shellを管理者権限で起動する。

[System.Environment]::SetEnvironmentVariable(
  "Path",
  $env:Path + ";C:hogehoge/wget/bin",
  "Machine"
)

上記のコマンドを実行することで「パスを通す」ことができる。

しかし、この状態だとWindowsに元からあるエイリアスと競合して使いたい方のwgetが仕えない。

そこで、プロファイルにエイリアス削除を追記する。

notepad $PROFILE

ファイルが存在しないと言われたら

New-Item -ItemType File -Path $PROFILE -Force
notepad $PROFILE

開いたメモ帳に以下を追加して保存

Remove-Item Alias:wget -ErrorAction SilentlyContinue

PowerShellを閉じて開き直して確認

Get-Command wget

Sourceがhogehoge/wget/bin/wget.exeになっていればOK。

URLリストを作る

wget単体でもページネーションを遡ることは可能らしいが、bloggerで作られたサイトでは上手くいかなかった。

そこで先にPythonでURLリストを作成する。

import requests
from bs4 import BeautifulSoup
import time

base_url = "https://fugafuga.com/"
urls = set()
next_url = base_url

while next_url:
    print(f"取得中: {next_url}")
    res = requests.get(next_url)
    soup = BeautifulSoup(res.text, "html.parser")
    
    # 記事URLを収集
    for a in soup.select("h3.post-title a, h2.post-title a"):
        urls.add(a["href"])
    
    # 次のページリンクを探す
    older = soup.select_one("a.blog-pager-older-link")
    next_url = older["href"] if older else None
    time.sleep(1)

# URLリストをファイルに保存
with open("C:hogehoge/urls.txt", "w") as f:
    for url in sorted(urls):
        f.write(url + "\n")

print(f"\n合計 {len(urls)} 記事のURLを収集した")

すると.txtにURLの一覧が出来上がる。

wgetを実行

ここから先は失敗例なので、次の章まで飛ばしてもよし。

さていよいよwgetの実行である。

cd "urls.txtのあるフォルダのパスを指定"
Remove-Item Alias:wget -ErrorAction SilentlyContinue
wget --input-file="urls.txt" --convert-links --no-check-certificate `
     --wait=1 --random-wait `
     -R "svg,ico,css,js" `

—no-check-certificateは大概のレンタルブログサービスだとナントカとナントカが一致しないために上手く実行できないので、強行突破するためにこの呪文を追加する。ウィルスを掴まされても自己責任だぞ。

しかし同じ名前のファイルが複数発生してしまい、blog-post.html.12のような数字の謎拡張子ファイルが大量発生してしまった。これでも中身が見れないことはないが、次のステップでmdファイルに一括変換するつもりだったので、これでは困る。

Pythonでwget実行

Pythonのスクリプト経由でwgetを実行することに。

import requests
from bs4 import BeautifulSoup
from pathlib import Path
import time
import re

input_file = Path(r"C:hogehoge\urls.txt")
output_dir = Path(r"C:hogehoge\html")
output_dir.mkdir(parents=True, exist_ok=True)

urls = input_file.read_text(encoding="utf-8").splitlines()

def sanitize(name):
    return re.sub(r'[\\/:*?"<>|]', "", name).strip()[:80]

for url in urls:
    try:
        # URLから年月を取得 例: /2019/10/blog-post.html
        parts = url.rstrip("/").split("/")
        year_month = "_".join(parts[-3:-1])  # 例: 2019_10

        res = requests.get(url)
        res.encoding = "utf-8"
        soup = BeautifulSoup(res.text, "html.parser")

        # タイトル取得
        title_tag = soup.select_one("h3.post-title, h2.post-title")
        title = sanitize(title_tag.get_text()) if title_tag else parts[-1].replace(".html", "")

        filename = f"{year_month}_{title}.html"
        out = output_dir / filename
        out.write_text(res.text, encoding="utf-8")
        print(f"保存: {filename}")
        time.sleep(1)

    except Exception as e:
        print(f"エラー: {url}{e}")

これで、日付+記事名のhtmlファイルとして保存完了。

あとは煮るなり焼くなり、よしなに。

まだリアクションがありません

なにか思いついたら送ってね