ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
DH(デジタル人文学)ツール情報の自動収集・記事生成システムの構築

DH(デジタル人文学)ツール情報の自動収集・記事生成システムの構築

DH分野のツール情報を追いかける デジタル人文学(DH)の分野では、OCR、IIIF、テキスト翻刻といった領域で新しいツールが継続的に開発されています。NDL(国立国会図書館)の ndl-lab や CODH(人文学オープンデータ共同利用センター)などの機関がGitHub上でツールを公開しており、研究者個人による開発も活発です。 こうした情報を体系的に収集し、カレントアウェアネスのように定期的にまとめる仕組みが欲しいと考え、自動収集・記事生成のシステムを構築しました。 収集対象 情報源は3種類です。 X (Twitter) では、DH分野で活発にツールを開発・公開している研究者や機関のアカウントを対象にしています。 RSSフィードでは、カレントアウェアネス・ポータル(国立国会図書館)の https://current.ndl.go.jp/rss.xml を取得しています。 GitHub では、DH関連のツールを公開している組織・個人の公開リポジトリの更新情報を GitHub API 経由で取得しています。 方法の検討 X投稿の取得 X の投稿取得にはいくつかの方法を検討しました。 方法 費用 結果 X API (Basic) $100/月 確実だが高コストのため不採用 Web検索(site:x.com/xxx) 無料 インデックスされたごく一部しか取れず不採用 RSSHub(セルフホスト) 無料 Xの内部API経由で全ツイート取得可能。Docker運用が必要で、GitHub Actions内での一時起動も検討したが、Playwright案のほうがシンプルなため不採用 Playwright(ログインなし) 無料 一部アカウントで0件。ログインウォールに阻まれ不採用 Playwright(Cookie認証) 無料 全アカウントで取得成功。毎日の取得であれば取りこぼしも少ない。採用 最終的に、Playwright で Cookie 認証を使う方法を採用しました。DevTools から auth_token と ct0 を手動で取得し、.x_cookies.json に保存する形です。GitHub Actions 上では Secret TWITTER_COOKIE から環境変数として渡しています。 Playwright による自動ログインも試みましたが、X のボット検出で失敗したため、手動取得に落ち着きました。Cookie は数ヶ月で期限切れになるため、定期的な更新が必要です。 AI要約・記事生成 方法 費用 結果 Claude Code 内で手動実行 プラン内 自動化できないためテスト用のみ Claude API (Anthropic直接) 従量課金 動作するが独自のAPI Key管理が必要で不採用 OpenRouter 従量課金 複数モデル選択可能、1回$0.05程度で採用 RSSフィード カレントアウェアネス・ポータルでは /feed エンドポイントがアイテム0件で、/rss.xml に30件のアイテムがあることを確認し、後者を使用しています。CODH のサイトはメンテナンス中でRSS取得ができなかったため、X 投稿で代替しています。 ...

Yahoo News記事のローカル保存手段の比較(SingleFile・Playwright・ArchiveBox・WARC・yt-dlp)

Yahoo News記事のローカル保存手段の比較(SingleFile・Playwright・ArchiveBox・WARC・yt-dlp)

Yahoo Newsの記事は一定期間で削除されることがあります。個人的な記録としてローカルに保存しておきたい場合、いくつかの手段があります。 ここでは、以下の5つの方法を同一の記事に対して実行し、結果を比較しました。 SingleFile CLI — 単一HTMLファイルとして保存 Playwright PDF — ページをPDF化 ArchiveBox — 複数形式を一括保存(WARC含む) WARC — 標準的なウェブアーカイブ形式 yt-dlp — 記事内の動画をダウンロード 比較結果 手段 形式 フォルダサイズ 広告 動画 SingleFile CLI 単一HTML 1.3MB 含まれる × Playwright PDF PDF 2.5MB 含まれにくい × ArchiveBox 複数形式一括 43MB 含まれる △ yt-dlp MP4 27MB - ○ ArchiveBoxの43MBにはSingleFile・PDF・WARC・本文抽出などが全て含まれています。全手段を併用した場合、1記事あたり約74MBのストレージを消費します。 SingleFile CLI SingleFile は、Webページを画像・CSS込みの単一HTMLファイルとして保存するツールです。 Chrome拡張版が有名ですが、CLI版もあります。 インストールと実行 npm install -g single-file-cli single-file 'https://news.yahoo.co.jp/articles/xxxxx' output.html 不要な要素の除去 --removed-elements-selector オプションで特定の要素を除去することもできます。 single-file 'https://news.yahoo.co.jp/articles/xxxxx' output.html \ --removed-elements-selector='header, footer, nav, aside, [id^="yads_"]' ただし、CSSセレクタの指定によっては記事の構成要素(配信元情報、更新日時など)まで意図せず削除してしまう可能性があるため、除去する場合は保存結果を確認する必要があります。 ...

researchmapの科研費と業績の紐付けをPlaywrightで自動化した

researchmapの科研費と業績の紐付けをPlaywrightで自動化した

はじめに researchmap は、日本の研究者が業績を管理・公開するためのプラットフォームです。論文や講演などの業績を登録するだけでなく、科研費(共同研究・競争的資金等の研究課題)との紐付けを行うことで、研究課題ごとの成果一覧を集約できます。 この紐付けについて、APIやCSVインポートでの一括設定ができないか調べたところ、調査した限りでは現時点ではWeb UIからの手動操作に限られるようでした。そこで、Playwrightによる自動化を試みました。 紐付けの方法を調べる researchmapでは、業績データの一括登録はJSONLやCSVファイルのインポートで可能です。一方、科研費と業績の紐付けについては、調査した限り、一括インポートでは設定できないようでした。 API設計書での確認 researchmap v2 API設計書を確認すると、以下のフィールドはすべて「更新不可」と記載されています。 research_projects(科研費)側: rm:published_paper_id(紐づいた論文の業績ID)→ 更新不可 rm:presentation_id(紐づいた講演の業績ID)→ 更新不可 rm:work_id(紐づいたWorksの業績ID)→ 更新不可 業績(論文・講演等)側: rm:research_project_id(紐づいた科研費ID)→ 更新不可 実際に検証 念のため、JSOLNインポートで identifiers.research_project_id を指定して検証しました。 {"insert":{"type":"presentations","id":"52101757"},"merge":{"identifiers":{"research_project_id":["51361068"]}}} 結果:インポート自体は「完了」と表示されましたが、紐付けは反映されませんでした。このフィールドは無視されるようです。 Web UIでは可能 一方、researchmapのWeb UI(編集画面)では、業績ごとに「共同研究・競争的資金等の研究課題」のプルダウンから科研費を選択して紐付けることができます。 この操作は1件ずつ手動で行う必要があり、件数が多いと手間がかかります。 Playwrightで自動化する Web UIでの手動操作を、Playwrightを使って自動化するPythonスクリプトを作成しました。 仕組み .env ファイルからresearchmapのログイン情報を読み込み Playwrightでブラウザを起動し、自動ログイン 各業績の編集ページ(/{slug}/{type}/{id}/edit)に移動 selectize.jsで実装されたプルダウンから、対象の科研費を自動選択 「決定」ボタンをクリックして保存 既に紐付け済みの業績は自動スキップ 編集画面のHTML構造 researchmapの編集画面では、科研費のプルダウンはselectize.jsで実装されています。 <select name="data[PublishedPapersIndex][_source][identifiers][research_project_id][]" class="form-control selectized" multiple="multiple" style="display: none;"> <option value="50040755" selected="selected">TEIを中心とした高度な歴史テキスト構築</option> </select> 実際の <select> は非表示で、selectize.jsが生成するカスタムUIで操作します。Playwrightでは以下のようにselectize入力をクリックし、ドロップダウンからオプションを選択します。 # selectize の入力エリアをクリックしてドロップダウンを開く selectize_input = page.locator(f'#{selectize_id}-selectized') await selectize_input.click() # ドロップダウンから該当の科研費を選択 option = page.locator(f'.selectize-dropdown .option[data-value="{project_id}"]') await option.click() # 「決定」ボタンで保存 submit = page.locator('button[name="save"][type="submit"]') await submit.click() 紐付け設定ファイル 紐付け対象はJSONファイルで管理します。 ...