プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • Python
  • 【Python】「BeautifulSoup」について
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【Python】「BeautifulSoup」について

05.28

  • miyabisan2
  • コメントを書く

この記事は3分で読めます

インストール

1
2
3
4
5
conda install beautifulsoup4
 
または
 
pip install beautifulsoup4

インポート

1
2
from bs4 import BeautifulSoup
import requests

BeautifulSoupの他にRequestsをimportします。(もしインストールしていない場合は事前にpipなどでインストールしておく必要があります。)

構文

1
BeautifulSoup(解析対象のHTML/XML,利用するパーサー)

BeautifulSoupで利用することができるパーサー

パーサー指定方法特徴
Python's html.parser"html.parser"追加ライブラリが不要
lxml's HTML parser"lxml"高速に処理が可能
lxml's XML parser"xml"XMLに対応し、高速に処理が可能
html5lib"html5lib"正しくHTML5を処理可能
何もインストールしていない環境だとデフォルトが「html.parser」になりますが、例えばlxmlをインストールしている環境だと自動的に他のパーサーが選択されてしまう可能性があります。なので基本的に明示的に指定するようにしましょう。

実装

Requestと組み合わせます。

1
2
3
4
5
6
7
response = requests.get('サイトのURL')
 
if response.status_code == 200:
  soup = BeautifulSoup(r.text) # HTMLの解析
  soup.h2 # 最初のh2を取得する。
else:
    raise # printなどでログ出力でも良いです。

タグ取得メソッド

単数のタグを取得

1
2
3
4
5
6
# h2を取得
soup.h2
 
または
 
soup.find('h2')

最初のh2を取得する。どちらを使っても良いのですが、findの方がおすすめです。なぜなら全てのタグを取得したい場合の構文が「find_all()」というメソッドがあるので、一つを取得する場合はfindを使った方がわかりやすい(可読性が高い)ためです。

テキストを取得

1
2
3
4
5
soup.h2.text
 
または
 
soup.h2.get_text()

h2のテキスト。これはget_text()ではなくtextを使った方が良いでしょう。理由は以下です。

  • .textの方が簡潔に書けるため。
  • Pythonの辞書型のget()が値が返ってこない場合はNoneが帰るのに、get_text()だとエラーになり紛らわしいため。

複数のタグを取得

1
soup.find_all('h2')

一つ目のタグを取得

1
soup.find_all('h2')[0]

これは「soup.find('h2')」と同じになります。

複数のタグを同時の検索

1
soup.find_all(['h2', 'h3'])

複数のタグの中から、テキストを取得

1
2
for h2_tag in soup.find_all('h2'):
    print(h2_tag.text)

find_allの結果はlist形式で値が返ってくるので、上記のようにfor文を使えます。また、enumerateなどの構文も使えます。

1
h2_text_list = [tag.text for tag in soup.find_all('h2')]

リスト内包表記を使って上記のようにh2のテキストのリストを作ったりすることもできます。

特定のclassを持つタグを取得

タグ指定だと件数が多すぎるケースが多いので通常はclass指定の方が良いです。

1
soup.find_all('span', class_='クラス名')

Pythonの文法のclassと区別するためにBeautifulSoupではclassの末尾にアンダースコアをつけるようです。

1
soup.find_all('span', {'class': 'クラス名'})

辞書で指定することも可能です。

複数のclassを検索
1
soup.find_all('span', class_=['クラス名1', 'クラス名2'])

検索範囲を狭くしてからタグを取得する手法

検索範囲を狭める。

1
soup.find('article').find_all(['h2', 'h3'])

記事の全HTMLから毎回全てのタグを取得してくるという形では非常に大量のタグが毎回ヒットしてしまいます。

そこで、findでまずarticleというタグ構造を取得してその中から必要なタグを取得します。

記事のボリュームの多いサイトであれば使えるので非常によく使うテクニックなので是非覚えておきましょう。

該当する要素を削除する。

1
2
soup.find('h2', class_='クラス名').extract()
soup.find_all('h2'')

指定したclass名の要素が消えます。

どちらを選べば良いのか?

「検索範囲を狭くする方法」を選びましょう。「該当する要素を削除する」のは破壊的な方法になってしまうためです。仮に消してしまった情報の中から別に欲しい情報があった場合にもう一度Requestsを使ってリクエストし直す必要があるのでリクエスト数が増えてしまいお相手のサーバーに余計に負荷をかけることになってしまいます。

XPathを使う。

lxmlというパッケージを使う必要があります。

1
pip install lxml

実装

例えば、h2のhref属性の値を取得するサンプルとしては以下のようになります。

1
2
3
4
soup = BeautifulSoup(response.text, features="lxml")
lxml_coverted_data = html.fromstring(str(soup))
data = lxml_coverted_data.xpath("//h2/a/@href")
print(data)

テーブルから情報を抽出する例

各情報を辞書に登録してそれをlistに格納していきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
list = []
table = soup.find('table', class_='tableのclass名')
tr_tags = table.find_all('tr', class_='trのclass名')
    
for tr_tag in tr_tags:        
    
    # 欲しい情報だけ抜き出す。
    madori, yatin, kyori = tr_tag.find_all('td')[2:5]
    
    # 取得したすべての情報を辞書に格納する
    d = {
        'madori': madori.text, # 中身の情報だけ取得する。
        'yatin': yatin.text, # 中身の情報だけ取得する。
        'kyori':kyori.text, # 中身の情報だけ取得する。
    }
    
    # 取得した辞書をd_listに格納する
    list.append(d)

なぜ[{辞書1},{辞書2}]のようなデータ構造にしているかといえば、今後データを何らかの表形式で保存していくことになるかと思いますが、その際に処理が非常に簡単になるためです。

スポンサーリンク
  • 2023 05.28
  • miyabisan2
  • コメントを書く
  • Python
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2023 06.04

    【Python】ログ出力ライブラリlogging

  2. 2023 06.08

    【Python】Scrapyのデバッグ方法

  3. 2023 05.28

    【Python】「Requests」の使い方

  4. 2023 05.30

    【Python】VSCodeで環境構築

  5. 2023 06.20

    【副業】クラウドソーシングで案件獲得の流れ

  6. 2023 06.06

    【Python】スクレイピングプログラムの実装時の細かい配慮

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【Python】「Requests」の使い方

【Python】スクレイピング結果をCSVに保存する。

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー