【Python】株価とニュース見出しの記事のデータセットを作る【macOS】

## 概要
株価とニュース記事の関係性を調べるためのデータセットなるものを作りたい

## NEWS API
まずはニュースの見出しを取得してみる。

以下でkey取得
https://newsapi.org/docs/get-started

こんな感じでcurlで取得できた
```
~/test ⌚ 4:10:45
$ curl https://newsapi.org/v2/everything -G \
    -d q="ヤフー" \
    -d from=2023-06-17 -d to=2023-06-17 \
    -d sortBy=popularity \
    -d apiKey=[API key]| jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1915  100  1915    0     0   7621      0 --:--:-- --:--:-- --:--:--  7816
{
  "status": "ok",
  "totalResults": 2,
  "articles": [
    {
      "source": {
        "id": null,
        "name": "Netafull.net"
      },
      "author": "コグレマサト",
      "title": "「LINE Search」のウェブ検索を「Yahoo!検索」へ切り替え",
      "description": "LINEとヤフーが検索事業における連携を強化し、2023年6月下旬より「LINE Search」のウェブ検索を「Yahoo!検索」へ切り替えることを発表しました。さらなるユーザー体験の向上を実現するためとしています。 「...\n投稿 「LINE Search」のウェブ検索を「Yahoo!検索」へ切り替え は ネタフル に最初に表示されました。",
      "url": "https://netafull.net/line/0131406.html",
      "urlToImage": "https://netafull.net/wp-content/uploads/2023/06/line-yah00psearch.jpg",
      "publishedAt": "2023-06-17T23:00:00Z",
      "content": "LINE20236LINE SearchYahoo!\r\nLINE Search20182LINE20196LINE Search\r\nLINE SearchLINELINELINEYahoo!\r\n2023101Z LINE LINE"
    },
    {
      "source": {
        "id": null,
        "name": "Traicy.com"
      },
      "author": "吉川 直輝",
      "title": "Yahoo!トラベル、「週末72時間タイムセール」を開催中　6月19日正午まで",
      "description": "ヤフーは、旅行予約サイト「Yahoo!トラベル」で、「週末72時間タイムセール」を、6月16日正午から19日正午まで開催している。 設定ホテルと宿泊代金の一例は、ポイントなどを即時利用した場合、ホテルサンシティ池袋（2名 […]\n投稿 Yahoo!トラベル、「週末72時間タイムセール」を開催中　6月19日正午まで は TRAICY（トライシー） に最初に表示されました。",
      "url": "https://www.traicy.com/posts/20230617272060/",
      "urlToImage": "https://www.traicy.com/wp-content/uploads/2023/06/screencapture-travel-yahoo-co-jp-feature-timesale-72h-2023-06-16-16_52_49.jpg",
      "publishedAt": "2023-06-17T05:15:33Z",
      "content": "Yahoo!7261619\r\n28,28029,4502235,574REI24,836JR25,394\r\nPayPay"
    }
  ]
}

~/test ⌚ 4:11:14
$ 

```
のちのちpythonでも実行できるようにする。
※ 無料版は1か月前までの記事までしか取ってこれないので注意。有料版は月額500ドルくらいする。高すぎぃ

## Yahoo Finance APIで株価を取得する
次は株価の取得。
以下参考にライブラリ取得(非公式なので注意)
https://pypi.org/project/yahoo-finance-api2/
https://nanjamonja.net/archives/1257
https://qiita.com/kawataku-89love/items/ca259242e6a7ff44ed4d
pandasは今は要らないや


以下、過去1ヶ月に対して株価が最高だった日と最低だった日を取得
```
$ cat stock.py
import sys
import datetime
import json
from yahoo_finance_api2 import share
from yahoo_finance_api2.exceptions import YahooFinanceError

my_share = share.Share('4689.T')
symbol_data = None
# 30日分の、5分置きのデータを取得
try:
    symbol_data = my_share.get_historical(share.PERIOD_TYPE_DAY,
                                          30,
                                          share.FREQUENCY_TYPE_MINUTE,
                                          5)
except YahooFinanceError as e:
    print(e.message)
    sys.exit(1)

# symbol_data['high']の中にNoneが含まれていて、そのままだとうまく最小値、最大値がとれないので、filterをかける
filtered_high = filter(lambda x: x is not None, symbol_data['high'])
filtered_low = filter(lambda x: x is not None, symbol_data['low'])
min_value = min(filtered_low)
max_value = max(filtered_high)
for timestamp, high, low in zip(symbol_data['timestamp'], symbol_data['high'], symbol_data['low']):
    if high == max_value:
        max_timestamp = timestamp
    if low == min_value:
        min_timestamp = timestamp

max_date=datetime.datetime.fromtimestamp(int(max_timestamp/1000)).strftime('%Y-%m-%d')
min_date=datetime.datetime.fromtimestamp(int(min_timestamp/1000)).strftime('%Y-%m-%d')
print("MAX:", max_date, ",", max_value)
print("MIN:", min_date, ",", min_value)

~/stock ⌚ 21:11:31
$ 
```
実行結果
```
~/stock ⌚ 21:11:31
$ python3 stock.py
MAX: 2023-06-15 , 364.3999938964844
MIN: 2023-06-01 , 344.0

~/stock ⌚ 21:14:03
$ 
```

## 株価の最大と最小の日のニュースを取得
上記で出力したMINとMAXの日のニュースをpythonで取得する

```
import requests
headers = {'X-Api-Key': 'APIキー'}

def get_article_titles(date):
    url = 'https://newsapi.org/v2/everything'
    params = {
        'q': 'ヤフー OR Zホールディングス',
        'sortBy': 'popularity',
        'from': f'{date}',
        'to': f'{date}'
    }
    response = requests.get(url, headers=headers, params=params).json()
    titles = []
    for article in response['articles']:
        title = article['title']
        titles.append(title)
    return titles

print("ARTICLE_MIX_VALUE:")
min_titles = get_article_titles(min_date)
print(min_titles)

print("ARTICLE_MAX_VALUE:")
max_titles = get_article_titles(max_date)
print(max_titles)
```
実行結果
```
$ python3 stock.py 
MAX: 2023-06-15 , 364.3999938964844
MIN: 2023-06-01 , 344.0
ARTICLE_MIX_VALUE:
['どうして、私がエンジニアに？(1) 「ITエンジニアのキャリアパスは1つじゃない」 - サイボウズ 向井咲人さん', 'Yahoo!きっず、25周年を記念し、子どもに人気のキャラクターや漫画とコラボした「検索お宝探し」を実施']
ARTICLE_MAX_VALUE:
['Yahoo! JAPAN、データ利活用のための効果的な分析を解説するオンラインカンファレンス「Yahoo! JAPAN DATA CAMP 2023」を7月19日に開催', 'LINEアプリでヤフー広告を開始\u3000「サーチ」を「検索」に一本化', 'ヤフー株式会社Yahoo! JAPAN、データ利活用のための効果的な分析を解説するオンラインカンファレンス「Yahoo! JAPAN DATA CAMP 2023」を7月19日に開催', 'Yahoo! JAPAN、データ利活用のための効果的な分析を解説するオンラインカンファレンス「Yahoo! JAPAN DATA CAMP 2023」を7月19日に開催']
```
株価が1ヶ月での最高値、最低値でのニュース記事のタイトルを取得できた。

## next action...
株価が上がったときと下がったときで
タイトルの単語のポジティブ度、ネガティブ度を出力してみる
参考: https://qiita.com/keiich/items/8da6fbdab604712107e5