6
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【失敗談】スクレイピングを約1時間学んだだけで作業時間が激減した件。

Last updated at Posted at 2020-04-15

失敗談

過去記事にて、競艇の順位予想をするプログラムを作成し、紹介しました。

↓過去記事については、下記リンクを参照してください。↓
【ディープラーニング】機械学習初心者が競艇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がなかったときに発生するValueErrorexcept文で無視しています。

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秒以上は時間を開けるようにしましょう。

リンク

BeautifulSoup 公式ドキュメント

6
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?