初めてのスクレイピング

# 初めてのスクレイピング
### スクレイピングとは？
スクレイピングとは、**Webサイトから特定の情報を集める技術**です。
効率的に情報収集ができるというメリットがある一方で、Webサイトに負荷をかけてしまったり法に触れてしまったりすることもありますので注意が必要です。

### 実際にやってみよう
今回は自分で作成したhtmlファイルをスクレイピングしてみたいと思います。
下記のように、12か月分の株価の動きをHTMLで記載し、Ubuntuでapatcheを立てて実行しました。

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>株価</title>
</head>

<body>
    <h1>0000 ABC Motors</h1>
    <div>
        <table>
            <thead>
                <th>日付</th>
                <th>始値</th>
                <th>高値</th>
                <th>安値</th>
                <th>終値</th>
                <th>出来高</th>
            </thead>
            <tbody>
                <tr class="ohlcv">
                    <td class="date">2024/01/01</td>
                    <td class="open">4880</td>
                    <td class="high">4909</td>
                    <td class="low">4783</td>
                    <td class="close">4790</td>
                    <td class="volume">378</td>
                </tr>
                <tr class="ohlcv">
                    <td class="date">2024/01/02</td>
                    <td class="open">5060</td>
                    <td class="high">5091</td>
                    <td class="low">4837</td>
                    <td class="close">4880</td>
                    <td class="volume">762</td>
                </tr>
　　　　　　　　　　　　　　<!-- 以下省略 -->
```

そして、下記がindex.htmlをスクレイピングする際に使用するコードです。
```python:scraiping_test.ipynb
import requests
import pandas as pd
import mplfinance as mpf
import matplotlib.pyplot as plt
from bs4 import BeautifulSoup

# 各行を格納するリスト
date = []
open_prices = []
high_prices = []
low_prices = []
end_prices = []
volume = []

# 5日,25日移動平均線を格納するリスト
moving_average_5days = [None for _ in range(5)]
moving_average_25days = [None for _ in range(25)]

# 対象のurlを指定する
url = "http://localhost"

# urlにアクセスする
res = requests.get(url)
# HTMLコンテンツを解析可能なオブジェクトに変換する
soup = BeautifulSoup(res.text, "html.parser")

# タイトルを取得する
title = soup.find("h1")

# tableタグのtbodyタグのtrタグの内容をすべて取得する
rows = soup.select("table tbody tr")

# 各行のデータを取得しリストに格納する
for row in rows:
    colums = row.find_all("td")
    if len(colums) > 1:
        date.append(colums[0].text)
        open_prices.append(int(colums[1].text))
        high_prices.append(int(colums[2].text))
        low_prices.append(int(colums[3].text))
        end_prices.append(int(colums[4].text))
        volume.append(int(colums[5].text))

# 5日移動平均線を求めてリストに格納する
for i in range(len(open_prices) - 5):
    num = sum(open_prices[i : i + 5]) / 5
    moving_average_5days.append(num)

# 25日移動平均線を求めてリストに格納する
for i in range(len(open_prices) - 25):
    num = sum(open_prices[i : i + 25]) / 25
    moving_average_25days.append(num)

#データフレームを設定する
df = pd.DataFrame(
    {
        "open" : open_prices,
        "high" : high_prices,
        "low" : low_prices,
        "close" : end_prices,
        "volume" : volume
    }
)

#インデックスを設定する
df.index = [pd.to_datetime(value) for value in date]

# グラフに描画する
plt.figure(figsize=(16, 9))
plt.plot(date, open_prices, "-", label="hajimarine")
plt.plot(date, high_prices, "-", label="takane")
plt.plot(date, low_prices, "-", label="yasune")
plt.plot(date, end_prices, "-", label="owarine")
plt.plot(date, moving_average_25days, "-", label="25SMA")
plt.plot(date, moving_average_5days, "-", label="5SMA")
plt.xticks([])
plt.figure(figsize=(16,9))
plt.bar(date, volume)
plt.title(title.text)
plt.legend()
plt.xticks([])
plt.show()
mpf.plot(df, volume=True)
mpf.show()
```

実際に出来上がったグラフは下記のとおりです。

・始値、終値、高値、安値、5日移動平均線、25日移動平均線の折れ線グラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784331/95b34865-15ac-aafb-ea9f-745942cc63d5.png)

・出来高の折れ線グラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784331/dacf6a3a-6d66-565d-ac1a-c08ff55e5091.png)

・株価のチャートと出来高の棒グラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784331/246342d3-bb0f-9011-cfdc-70fbd10eba6d.png)


次回は、スクレイピング結果を元に株価の予測をしてみたいと思います。