回り道しながら一歩ずつ

回り道しながら一歩ずつ

プログラミングのアウトプットが中心、その他ジャンル問わず気になったことを投稿するブログ

【Python | Beautifulsoup】スクレイピングアプリ(第1回)Webサイトから必要な情報を取得

topimage
今回は会社で毎日行っているルーティンワークを、自動化するためのツールづくりを(全3回)に分けて、お届けします!第1回は、Pythonの外部モジュールのBeautifulsoupRequestsを使用して、Webサイトから情報を取得する(Webスクレイピング)部分の作成です。思ったように動かなかったりエラーの解消に時間がかかったりと、かなり苦労しました。。

作るもの

・Webサイトから、前日に投稿されたニュース記事のタイトルとURLを取得し、Excelに自動入力するツール
 

機能要件

★Webサイトから必要な情報を取得
・取得した情報をExcelに書き込み
・情報を書き込むExcelファイルを選択

Webスクレイピングでよく聞く「Beautifulsoup」と「Requests」とは

Webスクレイピングググると必ず検索でヒットする、BeautifulsoupRequestsですが、そもそも何ができるのかちゃんと理解できていなかったので、改めて調べると以下のような認識、、ですが合ってますかね(;'∀')

Beautifulsoup・・HTMLやXMLからデータと抽出するためのPythonパッケージ
使用例) Requests・・HTTP通信でリクエストを送りレスポンスを受け取れるライブラリ

Beautifulsoupの使い方

Beautifulsoupは、サードパーティ製のライブラリですので、使用する場合はインポートする必要があります。

from bs4 import BeautifulSoup
これで使用できるようになりましたが、インスタンス化するときに`BeautifulSoup`と入力するのは長くて面倒ですし、入力ミスを引き起こす恐れがありますので、from bs4 import BeautifulSoup as bsなど、別名をつけるのが一般的です。

Requestsの使い方

Requestsは、Webサイトのテキスト情報の取得などに使うライブラリです。もちろん、こちらもインポートが必要です。

import Requests
Requestsは`get`や`post`といったメソッドがあり、活用できる幅が豊富です。自分はまだ、HTMLの取得くらいしか思いつきませんが…

ソースコード

まずは必要なモジュールのインポートとWebサイトから情報を取得するクラスを作成しました。動きはしますが、きっと無駄の多いソースコードになっていると思うので、今後改善していくつもりです。

#!usr/bin/python
# -*- coding: UTF-8 -*-

import requests
from bs4 import BeautifulSoup
from datetime import datetime
import openpyxl

target_day = "2020年7月15日"

# ↓Webサイトから情報を取得するクラス
class Webget:
    def __init__(self, url):
        self.target_url = url # URLを格納する変数
        self.html_data = '' # サイトから取得したhtmlソースを格納する変数
        self.news_url = ''

    # ↓指定サイトにアクセスして情報を取得する関数
    def webaccess(self):

        # ↓引数で渡されたURLにアクセスし、responseオブジェクトを取得
        self.html_data = requests.get(self.target_url)

        # ↓BeautifulsoupでHtmlソース(?)を取得できる認識です
        soup = BeautifulSoup(self.html_data.content, 'html.parser')

        # ↓(日付けの判定用)Beautiufulsoupで取得した値からタグを指定して抽出
        output_days_tag = soup.select("th")

        # ↓タグを取り除いてテキストだけをさらに抽出
        output_days = [i.text for i in output_days_tag]

        # ↓欲しい値-タイトル(タグあり)
        news_title_tag = soup.select("td a")

        # ↓タイトル(タグ無し)
        news_title = [i.text for i in news_title_tag]

        # ↓URLの取得
        news_url = [i["href"] for i in news_title_tag]

        target_news_title = []
        target_url = []
        i = 0

        # ↓ループ処理でニュース投稿日を変数'r'に追加
        for r in output_days:

            # ↓ニュース投稿日が指定日と一致するか判定
            if r == target_day:
                # ↓一致する場合、リストにタイトルとURLを取得
                target_news_title.append(news_title[i])
                url = news_url[i]
                # ↓URLが'http'で始まっているか判定
                if url.startswith("http"):
                    target_url.append(url)
                # ↓'http'で始ま禎ない場合は、付与する
                else:
                    target_url.append("https://www.ipa.go.jp" + url)
                i += 1
            # ↓ニュース投稿日が指定日より後か判定
            elif r > target_day:
                i += 1
                continue
            else:
                break

        for s in range(len(target_news_title)):
            print("タイトル:" + target_news_title[s] + " " + "URL:" + target_url[s])

wg = Webget(r'https://www.ipa.go.jp/security/announce/alert.html')
wg.webaccess()

実行結果がこちらです。

実行結果イメージ

何とか動いたんで、本日はここまでとします。