失敗談
過去記事にて、競艇の順位予想をするプログラムを作成し、紹介しました。
↓過去記事については、下記リンクを参照してください。↓
【ディープラーニング】機械学習初心者が競艇1位予想を作れるのか試してみた。
プログラムに関してはある程度の評価をいただきましたが、ひとつ気になることが私にはありました。
それは、データ収集の大変さでした。
Webページからデータを収集していたので、この作業を楽にするのはスクレイピングをすることだとはわかっていました。
しかし私は、食わず嫌いというのとディープラーニングで手一杯だった為、難しそうなスクレイピングの中身さえ確認せずにコピーアンドペーストをしてデータを集めていました。
実際にスクレイピングの基礎を学習してみて、まず取り掛かりやすさに驚き、私が必死にコピーアンドペーストして収集していたテキストが
<pre>テキスト</pre>
のみで囲われていたことに絶望しました。
つまり、基礎でも取得できる単純なソースコードで構成されていたという訳です。
これで私は、開発に取り掛かる前にきちんと設計することの大切さを学びました。
設計さえしていれば、より短い時間で、効率よく円滑に作業が進んでいたはずです。
設計することは基本だと思いますが、きちんとしないと私のようになってしまうので気をつけてください。
モジュール
import requests
from bs4 import BeautifulSoup
import time
- Requests
- BeautifulSoup4
これらは追加モジュールなのでターミナル(Mac)でインストールする必要があります。
$ pip install requests
$ pip install BeautifulSoup4
ソースコード
import requests
from bs4 import BeautifulSoup
import time
date = ["202004", "202003", "202002", "202001",
"201912", "201911", "201910", "201909",
"201908", "201907", "201906", "201905",
"201904", "201903", "201902", "201901"]
with open("scraping_data.txt", "a", encoding='utf-8') as f:
for month in date:
for day in range(1, 32):
try:
if num < 10:
url = "URL/{}/12/0{}.html".format(month, day)
else:
url = "URL/{}/12/{}.html".format(month, day)
except ValueError:
pass
response = requests.get(url)
response.encoding = response.apparent_encoding
bs = BeautifulSoup(response.text, "html.parser")
for pre in bs.find_all("pre"):
f.write(pre.text)
time.sleep(1)
print("{}: 書き込み完了".format(month))
Pythonの基礎は特に説明を付け加える必要がない場合の説明は省かせていただきます。
url
URLを見てみると、日付を変えるごとに
URL/202004/12/04.html
のようにURLの一部が変更されるだけなのでこれを利用して取得しました。
if-else
if num < 10:
url = "URL/{}/12/0{}.html".format(month, day)
else:
url = "URL/{}/12/{}.html".format(month, day)
1~9日では、URL内で「01」のように表現されているので分岐させています。
try-except
try:
if num < 10:
url = "URL/{}/12/0{}.html".format(month, day)
else:
url = "URL/{}/12/{}.html".format(month, day)
except ValueError:
pass
URL内に任意の日付が存在しない場合があったので、指定のURLがなかったときに発生するValueError
をexcept
文で無視しています。
requests
requests.get(url)
response = requests.get(url)
HTTPリクエストを送り、HTTPレスポンスを取得することができます。
これによりHTMLを取得することができます。
レスポンスのエンコーディング
response.encoding = response.apparent_encoding
日本語などでは、エンコーディングを適切に判断できずに、文字化けしてしまう可能性があります。
response.encoding
encodingプロパティは、サーバーから返されるレスポンスの文字エンコーディングで、これに従い、コンテンツを変換することができます。
response.apparent_encoding
サーバーから返された文字エンコーディングが不明な時にコンテンツの中身をチェックした上で、適切な文字エンコーディングを返してくれます。
response.text
取得したHTMLを表示します。
BeautifulSoup
bs = BeautifulSoup(response.text, "html.parser")
BeautifulSoupを使用するには
- 第一引数:HTMLを渡します。
- 第二引数:HTMLパーサーを渡します。種類は多数存在しますが、今回は最初から使える
"html.parser"
を使っています。
HTMLパーサー
HTMLを字句解析して、タグを判断してデータ構造として取得するプログラムのことです。
BeautifulSoup.find_all()
for pre in bs.find_all("pre"):
f.write(pre.text)
()内に指定されたタグをすべて取得します。
それをforループにかけることで、一つずつ指定のタグを取得することができます。
timeメソッド
import time
time.sleep(1) # 1秒間プログラムを停止する
time.sleep()
任意の時間の間プログラムを停止することができます。
スクレイピングをすることで重要なのは、相手サイトに迷惑をかけないようにすることです。
最低でも1秒以上は時間を開けるようにしましょう。