Pythonにできることは自動化しよう!【第10回 webスクレイピング(Beautiful Soup編)】

こんにちは、unogram管理人のうのちゅ〜です。

【Pythonにできることは自動化しよう!】シリーズとして、Pythonの基礎から順を追って学習し、作業の自動化・効率化を実現する能力を身に着けていきます。Pythonの基礎について学ぶだけで、大規模なコードを書かなくても十分に役に立つプログラムを記述することができるようになります。Pythonは気になるけど、プログラミングには苦手意識がある方も安心してトライしてみてください!

本シリーズでは、以下のようなことができるようになります。

  • ファイルの読み書き・管理
  • Webサイトからファイルをダウンロード
  • エクセルシート操作
  • PDF・ワード文書操作・テキスト抽出
  • 電子メール・SMS送信

うまく活用すれば作業に役立ちそうなワードがたくさん並んでいますね!

なお、本シリーズでは一部以下の書籍を参考にしています。「退屈なことをPythonにやらせる」ようになるためにはうってつけの書籍なので、ぜひ参考にしてみてください。

それでは見ていきましょう!



Webスクレイピングを実践してみよう(Beautiful Soup編)

前回は、Webスクレイピングの実践編その1として、webbrowserモジュール、requestsモジュールの使い方について、実際のコードを見ながら学習しました。今回は、Beautiful Soupを用いてwebページのHTMLを解析する方法にてついて学習します。前回の知識も応用しつつ、より実用的なwebスクレイピングのやり方を見ていきましょう!

Webサイトによってはスクレイピングを禁止しているものもあります。スクレイピングをする際は、あらかじめサイトの利用規約などを確認するようにしましょう。

Webスクレイピングで知っておきたい最低限のHTMLに関する知識

HTMLについて詳しくないという方でも、最低限の知識を抑えておけば十分Webスクレイピングをすることができます。これについては知っておきたい!という知識を厳選して紹介していきます。

そもそもHTMLって?

HTMLについて簡単に言うと、webページがどのような要素から構成されているか、どのように整形されているかを表す、拡張子が.htmlであるテキストファイルです。よって、このファイルを解析することで、webページのどこから欲しい情報を取得すれば良いのか、どこをクリックすれば良いのかなどというスクレイピングに必要なデータが得られるというわけです。

HTMLテキストの特徴は?

HTML自体は少し特殊なテキスト構成になっています。前回Chromeのデベロッパーツールから参照したHTMLファイルの画像を再掲します。デベロッパーツールの開き方については前回記事を参考にしてください。

画像からわかるように、テキストは山括弧<>で文字列が囲まれたタグと呼ばれるものによって囲まれています。画像では、<title>文字列</title>などが相当します。スラッシュ/が含まれていない方が開始タグで、含まれている方が終了タグと呼ばれます(終了タグがないものも存在します)。開始タグと終了タグでテキストが囲まれたものを、要素と呼びます。

タグはwebページがどのような構造になっているかを示す重要な要素です。ただ、webスクレイピングを始める段階では、「HTMLテキストにはタグがたくさん含まれていて、解析するときに重要なんだな!」程度の認識で大丈夫です。



Beautiful Soupを使ってみよう!

Beautiful Soupを使うと、PythonでHTMLからほしい情報を抽出することができます。導入から見ていきましょう。

準備

まずはBeautiful Soupをインストールする必要があります。現在はbeautifulsoup4モジュールが推奨されています。

%pip install beautifulsoup4

インストールが終わったら、さっそくインポートして使ってみましょう。少々まぎらわしいですが、インポートする際はbeautifulsoup4ではなく、bs4とします。webページにアクセスするためにrequestsモジュールもインポートしておきましょう。

import bs4
import requests

まずはrequestsモジュールを使ってunogramのトップページにアクセスしてみます。URLは'https://unolaboratory.com'です。requestsモジュールの使い方を忘れてしまった方は前回の内容を復習しておきましょう。

response = requests.get('https://unolaboratory.com')
response.raise_for_status()

ここからBeautiful Soupを使用していきます。requestsモジュールで取得したResponseオブジェクトのtext属性をbs4.BeautifulSoup()関数の引数に渡すと、BeautifulSoupオブジェクトが返されます。

uno_bs  = bs4.BeautifulSoup(response.text)
print(uno_bs)
# <!DOCTYPE html>
# <html lang="ja"><head><meta charset="utf-8"/><meta content="IE=edge" http-equiv="X-UA-Compatible"/><meta content="width=device-width, initial-scale=1.0, viewport-fit=cover" name="viewport"/>
# (以下省略)

上の例では、出力結果の冒頭部分のみを表示しています。さきほどのデベロッパーツールの画像に表示されていたHTMLのテキストが取得できていることがわかるでしょう。これでBeautiful Soupの第一歩は完了です。



select()メソッドを使ってHTMLを解析してみよう!

BeautifulSoupオブジェクトを取得できたら、次はHTMLの中身を解析してみましょう。BeautifulSoupオブジェクトのselect()メソッドに検索したい要素のCSSセレクタを渡すと、HTMLから該当する要素(開始タグと終了タグでテキストが囲まれたもの)を取得できます。

CSSセレクタとは、webページのデザインに関する内容が記述されるCSSにおいて、どの要素にどのようなデザインを施すかを指定するために使われるものです。具体的には、単純にtitledivにようなタグや.containerのようなCSSクラスを指定したり、複合的に'div script'として、「<div>要素の中の<script>要素」のような指定の仕方も可能です。単純なタグ指定では検索性が低いですが、パターンを組み合わせることで詳細な検索が可能になります。

それでは実際にselect()メソッドを使用してみましょう。引数にCSSセレクタ'img'を渡してみます。

uno_bs.select('img')
# [<img alt="unogram" class="site-logo-image header-site-logo-image" height="140" src="https://unolaboratory.com/wp-content/uploads/2020/08/logo_unogram6.png" width="640"/>,
# <img alt="" class="attachment-2240x1260 size-2240x1260 eye-catch-image wp-post-image" height="1260" loading="lazy" sizes="(max-width: 2240px) 100vw, 2240px" src="https://unolaboratory.com/wp-content/uploads/2020/10/sumbnail_blog_mod-8.jpg" 
# (以下省略)

上の例では出力結果を途中で省略していますが、実際に実行してみると多くの文字列が返されることがわかります。よく見るとこれらは<img>タグから始まる文字列のリストになっています。正確には、CSSセレクタによって検索されて該当した要素が、Tagオブジェクトのリストとなって返されたものです。

Tagオブジェクトをテキストとして取得したい場合は、str()関数を使用しましょう。取得したリストの1つ目の要素を使って試してみます。

str(uno_bs.select('img')[0])
# '<img alt="unogram" class="site-logo-image header-site-logo-image" height="140" src="https://unolaboratory.com/wp-content/uploads/2020/08/logo_unogram6.png" width="640"/>'

Tagオブジェクトの便利な属性・メソッド

Tagオブジェクトについてもう少し詳しく見ていきます。

attrs属性

attrs属性はタグのすべての属性の辞書になっています。さきほどの文字列がclassなどをキーとして、整理された形で扱うことができるので非常に便利です。

uno_bs.select('img')[0].attrs
# {'class': ['site-logo-image', 'header-site-logo-image'],
#  'src': 'https://unolaboratory.com/wp-content/uploads/2020/08/logo_unogram6.png',
#  'alt': 'unogram',
#  'width': '640',
#  'height': '140'}
get()メソッド

attrs属性では辞書の形でTagオブジェクトの属性を取得できましたが、get()メソッドを使用すれば、引数にキーを指定してその値を取得することもできます。例を見てみましょう。

uno_bs.select('img')[0].get('class')
# ['site-logo-image', 'header-site-logo-image']
getText()メソッド

TagオブジェクトのgetText()メソッドを使うと、要素の内部テキストを取得できます。要素がテキストを含まない場合、下の例のように空文字列が返されます。

uno_bs.select('img')[0].getText()
# ''

参考書の自動化例

本シリーズで参考にしている「退屈なことはPythonにやらせよう」では、次のような応用例にBeautiful Soupを応用して、簡単な自動化プログラムを作成しています。詳しい実装内容等についてはぜひ書籍を参照してみてください。

  • Google検索の上位結果をまとめて新しいタブで開く
  • Amazonの検索結果の商品ページをまとめて開く
  • web上のフリー画像を次々にダウンロードする
  • オンラインストアから商品カタログを作成する



まとめ

今回は、【Pythonにできることは自動化しよう!】シリーズ第10回として、Beautiful Soupの具体的な使用方法について解説しました。実際のHTMLテキストを使用し、どのように解析するかについて理解が深まったのではないかと思います。

次回はBeautiful Soupとは異なるアプローチでスクレイピングできるSeleniumをの使い方について紹介していきます。

さらに追加で詳しく学びたいという方は、下記の参考書などを使った学習にも挑戦してみてください。

おすすめ参考書

冒頭でも紹介しましたが、Pythonによる自動化に向けた学習は、本シリーズでも参考にしている次の書籍がおすすめです。「退屈なことをPythonにやらせる」ようになるためにはうってつけの書籍なので、ぜひ参考にしてみてください。