たまに困る
たまに昔の記事を確認したいことがありまして、それが 🔗 text の中だと困っちゃうんですよね。
当時は検索用のCGIを入れていましたけど、今は外しちゃったので調べようがないのです。
ちなみにtext→旧ブログ→現ブログ(ここ)の順で移行してきています。
🔗 旧ブログ はWordPressなので検索機能付きで困りませんし、現ブログも大丈夫。
何か良い方法はないものかと思いながら、Notionをガシガシ使っているうちに「あ、解決できるじゃん!」と気付いてしまいました。
textのデータをNotionに放り込んで、Notion内で検索すれば良いのですよ。
アップロードでお仕置き
ファイルをNotionにボンッと放り投げたら、タイムアウトしたのか途中までしか取り込めず。
200を超えるファイルを一気にやったのがいけなかったのか 制限(12時間後に会いましょう) がかけられてしまって、この日の作業は終了・・・。
翌日、Zipにまとめてから投げたら全部取り込めました。
NotionでChatGPT-4.1が使えます
ちょっと話がズレますが、このあとの作業でAIを活用しています。
先日、 NotionでChatGPT-4.1が使えるようになった とXで知ったので、今回利用してみました。
現在はホーム画面でのみ利用可能です。
NotionでChatGPT-4.1
整形作業
文字コード変換
Zipで取り込めたんですけど、 きれいに文字化け (変な日本語)しまして、人間の私には読むことができませんでした・・・。
ああ、あなたShift-JISだったもんね・・・ということで文字コードを変換したいのですが、さすがに200を超えるファイルをちまちまと変換したくありません。
このときWindowsを使っていたので、PowerShellで一括変換する方法をNotion AIに教えてもらいました。
⚠️ コードはあくまでもサンプルですので、ご注意ください。
# 元フォルダ・出力フォルダ
$inputFolder = "C:\\input_html"
$outputFolder = "C:\\output_html"
# htmlファイルをサブフォルダまで再帰で取得
Get-ChildItem $inputFolder -Recurse -Filter *.html | ForEach-Object {
$inputFile = $_.FullName
# 出力先の相対パスを作成
$relativePath = $_.FullName.Substring($inputFolder.Length).TrimStart('\\')
$outputFile = Join-Path $outputFolder $relativePath
# 出力先フォルダがなければ作成
$outputDir = Split-Path $outputFile
if (!(Test-Path $outputDir)) {
New-Item -ItemType Directory -Path $outputDir -Force
}
# Shift-JISで読み込み
$content = Get-Content $inputFile -Encoding Default
# BOM付きUTF-8で書き出し
[System.IO.File]::WriteAllLines(
$outputFile,
$content,
[System.Text.Encoding]::UTF8
)
}
html → txt 形式へ変換
文字変換も終わり、再度Notionに取り込みましたら、ところどころでテーブルやデータベースが自動生成されてしまったので、いったん全ファイルからhtmlタグを除去しました。
元ファイルは私が一から手書きのものなので、htmlの書き方がおかしかったりしたのかしら。
変換の仕方はやっぱりNotion AIで。
このとき、唐突に「あ、Goでやろう」と思って、Go用にコードを書いてもらいました。
2年振りに触るGo、すっかり忘れていました。
⚠️ コードはあくまでもサンプルですので、ご注意ください。
package main
import (
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"golang.org/x/net/html"
)
func extractText(n *html.Node, sb *strings.Builder) {
if n.Type == html.TextNode {
sb.WriteString(n.Data)
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
extractText(c, sb)
}
}
func htmlToText(htmlStr string) string {
doc, err := html.Parse(strings.NewReader(htmlStr))
if err != nil {
log.Printf("Parse error: %v", err)
return ""
}
var sb strings.Builder
extractText(doc, &sb)
return sb.String()
}
func main() {
inputDir := "C:\\\\Users\\\\パパ\\\\Documents\\\\htmls"
outputDir := "C:\\\\Users\\\\パパ\\\\Documents\\\\texts"
// 出力先ディレクトリを作成
os.MkdirAll(outputDir, os.ModePerm)
// htmlファイルをすべて処理
files, err := filepath.Glob(filepath.Join(inputDir, "*.html"))
if err != nil {
log.Fatal(err)
}
for _, file := range files {
data, err := ioutil.ReadFile(file)
if err != nil {
log.Printf("Read error: %v", err)
continue
}
text := htmlToText(string(data))
base := filepath.Base(file)
outname := strings.TrimSuffix(base, filepath.Ext(base)) + ".txt"
outpath := filepath.Join(outputDir, outname)
ioutil.WriteFile(outpath, []byte(text), 0644)
log.Printf("変換完了: %s → %s", file, outpath)
}
}
もう少し整形
ムダな改行なんかは、VS Codeの置換機能で一括削除。
Notionにて
データベース化
空のデータベースを用意して、取り込んだデータをドラッグ・アンド・ドロップ。
AI要約と、鑑賞した映画
ファイルごとにAIで要約と、その中で鑑賞した映画を抜き出してもらいました。
映画のほうは大体合っているようですが、CDのタイトルなんかも間違えて取ってきたりしていました。まあいいけどね。
こんな感じ
データベース
レコード
まとめ
一連の作業はこんな感じでありました。
この記事を書いていて気付いたのですが、 Notionに入れなくてもVS Codeのフォルダー内検索で全文検索できたわ・・・。
いや、でも、スマホみたいに元データを持たないデバイスだとそれもできないから・・・と自分を慰めております。