BeatutifulSoupのfind_all使い方[Python/スクレイピング]

programming.jpg

こんにちは

みなさんはPythonでスクレイピングをする時に何を使いますか?

私はBeatutifulSoupを使用しています。

今回はBeautifulSoupで最も使用するfind_allの使い方を見ていきます。

find_allの引数について

find_all(name, attrs, recursive, text, limit, **kwargs)

公式ドキュメントより引用

find_allには6つの引数があります。

  • name
  • attrs
  • recursive
  • text
  • limit
  • **kwargs

6つの引数を使うことで、自分が欲しい情報をスクレイピングすることができます。

スクレイピングするもの

今回スクレイピングするものは、以下になります。

本記事の内容はJupyterLabなどの対話型の環境で実行してみてください。

html_doc = """
<html><head><title>カレーのおすすめ具材</title></head>
<body>
<p class="title"><b>カレーの具材一覧</b></p>

<p class="food">野菜編
<a href="http://example.com/potatoes" class="vegetable" id="link1">じゃがいも</a>,
<a href="http://example.com/carrots" class="vegetable" id="link2">にんじん</a> ,
<a href="http://example.com/onion" class="vegetable" id="link3">たまねぎ</a>,
</p>
</body></html>
"""

検索方法

それでは検索方法を見ていきましょう。

まず、必要な物をインポートしましょう。

from bs4 import BeautifulSoup
import re

BeautifulSoupはもちろんのこと。正規表現でスクレイピングをするために、モジュールreも必要になります。

インポートしておきましょう。

スクレイピングするhtml_docをBeautifulSoupで解析して、soupに格納してください。

soup = BeautifulSoup(html_doc)

name引数

name引数はタグの名前だけを対象に検索をしてくれます。

初めにtitleタグを取得してみましょう。

soup.find_all("title")
#[<title>カレーのおすすめ具材</title>]

タグで認識するのでclass=”title”には反応しませんでしたね。

次にaタグを取得します。

soup.find_all("a")
# [<a class="vegetable" href="http://example.com/potatoes" id="link1">じゃがいも</a>,
#  <a class="vegetable" href="http://example.com/carrots" id="link2">にんじん</a>,
#  <a class="vegetable" href="http://example.com/onion" id="link3">たまねぎ</a>]

aタグを全て取得することができましたね。

text引数

text引数はタグに挟まれている文字列を検索する引数です。

文字列で検索

「じゃがいも」という文字列を検索してみましょう。

soup.find_all(text="じゃがいも")
# ['じゃがいも']

text引数を用いることで、じゃがいもを取得することができましたね。

しかし、今のままのtext引数では完全一致した文字列しか取得することができません。

試しに「いも」という文字列を検索してみましょう。

soup.find_all(text="いも")
# []

完全に一致していないため、なにも取得することができませんでした。

このままだと使いづらいですよね。

正規表現で検索

それでは正規表現で、検索してみましょう。

モジュールreをインポートして、re.compile(“いも”)と記述しましょう。

import re
soup.find_all(text=re.compile("いも"))
#['じゃがいも']

文字列である「じゃがいも」を取得することができましたね。

正規表現を使うことで、目的の文字列が含まれる文章を抜き出せるのは使い勝手が良いのではないでしょうか。

**kwargs引数

**kwargs引数とはどんなものでも、タグの属性の1つとして解釈し検索してくれる引数です。

idで検索

idで検索したいという時は、以下のように記述します。

soup.find_all(id="link1")
#[<a class="vegetable" href="http://example.com/potatoes" id="link1">じゃがいも</a>]

クラスで検索

クラスを検索する時は、class_(アンダーバー)と記載してください。

classは予約語(使用できない文字列)なので注意してください。

soup.find_all(class_="title")
#[<p class="title"><b>カレーの具材一覧</b></p>]

2つの条件を設定して検索

このキーワード引数に複数の属性を渡して、検索することも可能です。

条件を2つ以上設定する時は、条件と条件をカンマ(,)で区切ります。

「idの条件」と「テキスト」が一致しているものを抽出

「idが設定されているもの」かつ「テキストが”じゃがいもの”」のものを抽出してみます。

soup.find_all(id=True,text="じゃがいも")
#[<a class="vegetable" href="http://example.com/potatoes" id="link1">じゃがいも</a>]

attrs引数

atts引数は辞書型で検索する引数です。

soup.find_all(attrs={"class":"title"})
#[<p class="title"><b>カレーの具材一覧</b></p>]

classがtitleの物を取得することが可能です。

またタグとクラス名を指定したい場合は、以下のように検索します。

soup.find_all("p",attrs={"class":"title"})
#[<p class="title"><b>カレーの具材一覧</b></p>]

pタグの中のclassがtitleの物を取得することができます。

limit引数

limit引数は取得する数を指定することができます。

aタグの取得をlimit引数で指定してみましょう。

soup.find_all("a",limit=1)
#[<a class="vegetable" href="http://example.com/potatoes" id="link1">じゃがいも</a>]

limit=1とすることで、aタグを1つだけ取得することができましたね。

recursive引数

Beautiful Soupはすべての全ての子孫要素を調べます。

そのため、直下の子要素しか調べたくない場合に、recursive=Falseを使用します。

soup.find_all("title",recursive=False)
#[]

今回の用意したものには、子要素が存在しません。

そのため、何も取得することができませんでした。

最後に

今回はBeautifulSoupのfind_allメゾットの使い方を見てきました。

find_allメゾットはとても使いやすいです。

find_allとfindの2つがあれば、ほとんど解決できる!と公式ドキュメントにも書いてあります。

もっと深堀したい!と言う方は、公式ドキュメントを見ることをオススメします。

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA