議案・賛否データ

対象: 衆議院 / 参議院(記名投票)

👀 ざっくり言うと

国会に提出される法案・予算案などの議案と、その採決結果を公式サイトから自動収集しています。 参議院の記名投票については議員個人ごとの賛否を記録し、衆議院および会派単位の賛否も記録します。 同じ会派の多数派から逸脱した「造反投票」も自動で検出されます。

🔄 データの流れ

graph TD
    A["参議院公式サイト
記名投票ページ"]:::source B["SmartNews SMRI
議案データセット(gian.json)"]:::source M["管理画面からの手動入力
CLI / 直接 SQL"]:::source P1["投票リンク収集
回次ごとに記名投票一覧ページを取得"]:::process P2["投票結果パース
議員別の賛否をHTMLから抽出"]:::process P3["議案メタデータ取り込み
議案名・提出者・採決日をDBに投入"]:::process P4["議案マッチング
投票結果の案件名でProposalを特定"]:::process P5["個人賛否投入
Bronze層に追記(SMRI 経路)"]:::process P6["Gold層への確定
政治家IDに紐付けて確定値を反映(記名投票は照合後ここへ直接投入)"]:::process P7["会派賛否集計
個人賛否から会派多数派を判定・造反を検出"]:::process P8["議案の手動登録・編集
議案作成・賛否確定・提出者マッチング"]:::process T_PROP["proposals
テーブル(議案)"]:::table T_SUB["proposal_submitters
テーブル(議案提出者)"]:::table T_DEL["proposal_deliberations
テーブル(議案審議)"]:::table T_EXT["extracted_proposal_judges
テーブル(抽出議案賛否 / Bronze層)"]:::table T_PJ["proposal_judges
テーブル(議案賛否)"]:::table T_PVR["proposal_vote_records
テーブル(議案賛否レコード)"]:::table H["BigQuery公開
sagebase スキーマ"]:::public A --> P1 P1 --> P2 B --> P3 P3 --> T_PROP P3 --> T_SUB P3 --> T_DEL P2 --> P4 P3 --> P4 P3 --> P5 P4 --> P6 P5 --> T_EXT P5 --> P6 P6 --> T_PJ P6 --> P7 P7 --> T_PVR M --> P8 P8 --> T_PROP P8 --> T_SUB P8 --> T_PJ P8 --> T_PVR T_PROP --> H T_SUB --> H T_DEL --> H T_PJ --> H T_PVR --> H classDef source fill:#ffffff,stroke:#1a1a1a,stroke-width:2.5px,color:#1a1a1a classDef process fill:#ffffff,stroke:#737373,stroke-width:1px,color:#1a1a1a classDef table fill:#ffffff,stroke:#1a1a1a,stroke-width:1.5px,stroke-dasharray: 6 3,color:#1a1a1a classDef public fill:#1a1a1a,stroke:#1a1a1a,stroke-width:2.5px,color:#ffffff
元データ 加工 DB 公開
📂 技術的な詳細(開発者向け)

スクレイパー・インポーター

データソーススクリプト主要ロジック
参議院公式(記名投票)
https://www.sangiin.go.jp/
sagebase import-sangiin-roll-call-votes回次142〜221の記名投票一覧ページから投票リンクを取得し、各ページをパースして議員別賛否を取得。案件名でProposalを照合し、政治家IDに紐付けてproposal_judgesへ投入する(会派方針は roll-call 内の多数決で算出し、逸脱をis_defectionとして立てる)
SmartNews SMRI(議案データ)
https://github.com/smartnews-smri/house-of-councillors
scripts/import_sangiin_gian.pyGitHub公開のgian.jsonから議案名・提出者・採決日などのメタデータを取り込み
会派賛否の集計と造反検出scripts/match_proposal_group_judges.pyBronze層の個人賛否をparliamentary_groupsと突合し、多数派を会派賛否として登録。多数派と異なる個人投票にis_defectionを立てる
管理画面からの手動入力(CLI / psql 直接 SQL)sagebase CLI コマンド群 + psql (ADR 0023 で旧 Streamlit admin UI を全廃)議案の新規登録・編集、Bronze層からGold層への個人賛否の最終確定、記名投票結果のオーバーライド、提出者の手動マッチングを提供

DBテーブル(PostgreSQL)

テーブル説明
proposals議案の基本情報(議案名・大分類・小分類・採決日)
proposal_submitters議案の提出者(政治家・会派・内閣)
proposal_deliberations議案の審議履歴
extracted_proposal_judgesBronze層。スクレイピング直後の個人賛否(追記専用)
proposal_judgesGold層。議員個人の賛否(記名投票のみ)
proposal_vote_records会派・議員個人の賛否レコード(会派単位は多数派判定結果)

dbtモデル(内部 Data Vault 層 / 非公開)

モデル役割
hub_proposalProposal のハブ(ビジネスキー = sagebase_id)
sat_proposalProposal の属性サテライト
link_proposal_judge議案 ↔ 政治家賛否 のリンク(キー = 賛否記録自身の sagebase_id)
sat_proposal_judge個人賛否の属性サテライト
link_proposal_submitter議案 ↔ 提出者 のリンク(キー = 提出者記録自身の sagebase_id。未名寄せの提出者が居るため政治家は属性側で保持)
sat_proposal_submitter提出者の属性サテライト
link_proposal_deliberation議案 ↔ 審議した会議体 のリンク(キー = 審議記録自身の sagebase_id。会議は 84.3% が未特定なため属性側で保持)
sat_proposal_deliberation議案審議の属性サテライト
link_proposal_meeting_occurrence議案 ↔ 会議 の出現リンク(キー = 出現記録自身の sagebase_id)
sat_proposal_meeting_occurrence議案の会議出現の属性サテライト

BigQuery公開テーブル

テーブルデータセット
proposalssagebase
proposal_submitterssagebase
proposal_deliberationssagebase
proposal_judgessagebase
proposal_vote_recordssagebase