News API を使ってニュース記事を取得する

基本的には有料サービスだが、開発目的なら制限付きで無料で使用できる。
制限(2024年6月現在)
- 記事は24時間遅れ
- 1か月前までの記事を検索
- 1日あたり100件のリクエスト
NEWS APIでは、トピックやキーワードなどを指定して過去のニュース記事を検索する Everything と、国やカテゴリーなどを指定して現在のトップニュースを取得する Top headlines の二つのエンドポイントが提供されている。
Everything エンドポイント(/v2/everything)
リクエスト
| パラメータ | 機能 | デフォルト値 | 備考 |
|---|---|---|---|
| apiKey | API key | 必須 | HTTP ヘッダで指定可 |
| q | 検索キーワード | - | 論理条件を指定可 |
| searchIn | 検索対象フィールド | 全てのフィールド | 複数指定可 |
| sources | ニュースソースID | - | 複数指定可 |
| domains | 検索対象ドメイン | - | 複数指定可 |
| excludeDomains | 除外するドメイン | - | 複数指定可 |
| from | 検索対象範囲 | 最も古い日時 | ISO 8601 形式 |
| to | 検索対象範囲 | 最も新しい日時 | ISO 8601 形式 |
| language | 言語 | 全ての言語 | 日本語指定不可 |
| sortBy | 出力順序 | publishedAt | 他に relevancy, popularity |
| pageSize | 最大記事数/ページ | 20 | 最大 100 |
| page | ページ番号 | 1 |
レスポンス
| フィールド | 内容 | データ型 | 備考 |
|---|---|---|---|
| status | リクエスト結果 | string | ok または ステータスコード |
| totalResults | ヒットした総記事数 | int | 返却は pageSize 単位 |
| articles | 検索した記事 | list | 以降のフィールドの繰り返し |
| source | ニュースソースIDと名前 | id + name | |
| author | 著作者 | string | |
| title | タイトル | string | |
| descripriotn | 記事要約 | string | |
| url | 記事URL | string | |
| urlToImage | 記事画像URL | string | |
| publishedAt | 日時 | string | ISO 8601 形式 |
| content | 記事内容 | string | None が多い |
過去 5 年間に大小 150,000 を超えるさまざまなソースから公開されたすべての記事を検索。
このエンドポイントは、ニュース分析や記事の発見に最適。
Top headlines エンドポイント(/v2/top-headlines)
リクエスト
| パラメータ | 機能 | デフォルト値 | 備考 |
|---|---|---|---|
| apiKey | API key | 必須 | HTTP ヘッダで指定可 |
| country | 国記号 | 全ての国 | 日本は jp |
| categry | カテゴリ | 全てのカテゴリ | business, entertainment, general, health, science, sports, technology |
| sources | ニュースソースID | - | 複数指定可 |
| domains | 検索対象ドメイン | - | 複数指定可 |
| q | 検索キーワード | - | |
| pageSize | 最大記事数/ページ | 20 | 最大 100 |
| page | ページ番号 | 1 |
レスポンス
Everythingと同じ。
国、カテゴリ、および単一の発行者の最新ニュースのヘッドラインを返す。
これは、ニュース ティッカーや、最新のニュース ヘッドラインをライブで使用したい場合に最適。
スキャンできるパブリッシャーの小さなサブセットを取得するために使用できるマイナー エンドポイントも
ソース /v2/top-headlines/sources
上位の見出しを取得するために利用できる最も注目すべきソースに関する情報 (名前、説明、カテゴリを含む) を返す。
このリストは、利用可能なオプションの一部をユーザーに表示するときに、ユーザーに直接パイプで渡すことができる。
カテゴリー
- business
- entertainment
- general
- health
- science
- sports
- technology
国別検索「country」
| コード | 国名 |
|---|---|
| ae | アラブ首長国連邦 |
| ar | アルゼンチン |
| at | オーストリア |
| au | オーストラリア |
| be | ベルギー |
| bg | ブルガリア |
| br | ブラジル |
| ca | カナダ |
| ch | スイス |
| cn | 中国 |
| co | コロンビア |
| cu | キューバ |
| cz | チェコ |
| de | ドイツ |
| eg | エジプト |
| fr | フランス |
| gb | イギリス |
| gr | ギリシャ |
| hk | 香港 |
| hu | ハンガリー |
| id | インドネシア |
| ie | アイルランド |
| il | イスラエル |
| in | インド |
| it | イタリア |
| jp | 日本 |
| kr | 韓国 |
| lt | リトアニア |
| lv | ラトビア |
| ma | モロッコ |
| mx | メキシコ |
| my | マレーシア |
| ng | ナイジェリア |
| nl | オランダ |
| no | ノルウェー |
| nz | ニュージーランド |
| ph | フィリピン |
| pl | ポーランド |
| pt | ポルトガル |
| ro | ルーマニア |
| rs | セルビア |
| ru | ロシア |
| sa | サウジアラビア |
| se | スウェーデン |
| sg | シンガポール |
| si | スロベニア |
| sk | スロバキア |
| th | タイ |
| tr | トルコ |
| tw | 台湾 |
| ua | ウクライナ |
| us | アメリカ合衆国 |
| ve | ベネズエラ |
| za | 南アフリカ |
取得サンプル(Perl)
use CGI;
use Encode;
use utf8;
use LWP::UserAgent;
use JSON::PP;
$url = "https://newsapi.org/v2/top-headlines?country=jp&category=technology&apiKey=キー";
$news_data = Get_News($url);
sub Get_News {
my ($url) = @_;
my $ua = LWP::UserAgent->new;
# $ua->agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3");
my $response = $ua->get($url);
if ($response->is_success) {
my $json_data = decode_json($response->decoded_content);
# HTML出力用変数
my $html_output = '';
# 各記事の情報を抽出してHTML形式に整形
foreach my $article (@{$json_data->{articles}}) {
my $title = $article->{title};
my $source_name = $article->{source}->{name};
my $author = $article->{author} // 'Unknown'; # 著者が存在しない場合はUnknownとする
my $news_img = $article->{urlToImage} // 'https://sample.com/images/no-image.png'; # noimage画像設定
my $news_url = $article->{url};
my $published = $article->{publishedAt};
my $news_contents = $article->{description};
# 日付をフォーマットする
my ($year, $month, $day, $hour, $minute) = $published =~ /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):/;
my $formatted_date = sprintf("%04d年%02d月%02d日 %02d:%02d", $year, $month, $day, $hour, $minute);
$html_output .= <<EOM;
<div>
<h2>$title</h2>
<div style="display:flex;">
<div><img src="$news_img" style="max-width:600px;" /></div>
<div style="padding:0 0 0 10px;">
<p><a href="$news_url" target="_blank">$news_url</a></p>
<p>$formatted_date</p>
<p>$source_name</p>
<p>$author</p>
</div>
</div>
<p>$news_contents</p>
</div>
<hr>
EOM
}
$content = $html_output;
} else {
$content = "Failed to fetch $url" . $response->status_line;
}
return $content;
}