BeautifulSoup4でhrefの値を捕まえる方法
- 作成日: 2020-11-25
- 更新日: 2023-12-24
- カテゴリ: BeautifulSoup4
BeautifulSoup4でhrefを捕まえる
Pythonの外部ライブラリに「BeautifulSoup4(ビューティフル・スープ・フォー)」というライブラリがあります。
このライブラリはHTML/XMLを解析するときに使われるパーサーです。
BeautifulSoup4を使うと簡単にHTMLの要素の属性href
の値を取得することが出来ます。
この記事ではBeautifulSoup4を使ってHTMLの要素が持つhref
の値を取得する方法を解説します。
具体的には↓を見ていきます。
- BeautifulSoup4の簡単な使い方
- find()でhrefを得る
- find_all()でhrefを得る
BeautifulSoup4の簡単な使い方
BeautifulSoup4は↓のようにBeautifulSoup
をオブジェクトにして使います。
from bs4 import BeautifulSoup
html = '<p>test</p>'
soup = BeautifulSoup(html, 'html.parser')
print(type(soup))
# <class 'bs4.BeautifulSoup'>
bs4.BeautifulSoup
はbs4.element.Tag
を継承したクラスです。
よってbs4.BeautifulSoup
が持っているメソッドのほとんどはbs4.element.Tag
が持っているメソッドです。
この記事で紹介するfind()
やfind_all()
, select()
などはbs4.element.Tag
で定義されています。
find()でhrefを得る
bs4.element.Tag
が持つfind(ファインド)
メソッドは要素を検索するメソッドです。
基本的には第1引数にタグ名を指定して使います。
el = soup.find('p')
find()
メソッドは最初に見つかった要素をbs4.element.Tag
で返します。
見つからなかった場合はNone
を返します。
bs4.element.Tag
はget()
というメソッドを持っています。
このget()
を使うと、そのタグの属性値を得ることが出来ます。
たとえばタグが属性href
を持っている場合、↓のようにすることで、その属性値を得ることが出来ます。
val = el.get('href')
get()
メソッドは属性が見つからなかった場合はNone
を返します。
属性が見つからなかった場合のデフォルト値を指定したい場合はget()
の第2引数に値を指定します。
val = el.get('href', 'default value')
find()
で要素を検索し、その要素の属性値を得るサンプル・コードは↓のようになります。
from bs4 import BeautifulSoup
html = '<a href="/home">Go to home</a>'
soup = BeautifulSoup(html, 'html.parser')
el = soup.find('a')
print(el.get('href'))
# /home
また、find()
の代わりにタグにドット演算子でアクセスすることで、その演算子についているタグを辿ることも出来ます。
soup.a
このドット演算子によるタグの参照を使うと、↓のように書くことも出来ます。
from bs4 import BeautifulSoup
html = '<a href="/home">Go to home</a>'
soup = BeautifulSoup(html, 'html.parser')
print(soup.a.get('href'))
# /home
find()
メソッドは引数attrs
に属性と属性値を指定することが出来ます。
特定のhref
の値を参照したい時に便利です。
具体的には↓のように使います。
soup.find('a', attrs={ 'href': '/home' })
サンプル・コードは↓のようになります。
from bs4 import BeautifulSoup
html = '<a href="/home">Go to home</a>'
soup = BeautifulSoup(html, 'html.parser')
a = soup.find('a', attrs={ 'href': '/home' })
print(a.get('href'))
# /home
attrs
引数の属性値にはリストや正規表現オブジェクトを指定することも出来ます。
リストの場合はOR
検索になります。
soup.find('a', attrs={ 'href': ['/home', '/sitemap'] })
正規表現オブジェクトは↓のように指定します。
import re
soup.find('a', attrs={ 'href': re.compile(r'/h.*') })
特定のclass
の要素のhref
を参照したい場合は↓のように書くことが出来ます。
↓はblue
というクラス名を持つ要素のhref
を参照する例です。
a = soup.find('a', class_='blue')
print(a.get('href'))
id
で検索したい場合は引数にid
を指定します。
a = soup.find('a', id='red')
print(a.get('href'))
find_all()でhrefを得る
find()
メソッドは単一の要素を得るメソッドでしたが、検索にヒットした要素をすべて得るメソッドもあります。
その名もfind_all(ファインド・オール)
です。
find_all()
メソッドも基本的にはfind()
メソッドと同じ使い方をします。
たとえばリンクの要素をまとめて検索し、それらすべての要素のhref
を参照したい場合は↓のようなコードになります。
from bs4 import BeautifulSoup
import re
html = '''
<a href="/red">Red</a>
<a href="/green">Green</a>
<a href="/blue">Blue</a>
'''
soup = BeautifulSoup(html, 'html.parser')
links = soup.find_all('a')
for link in links:
print(link.get('href'))
find_all()
でもfind()
のようにattrs
やclass_
などの引数を使うことが出来ます。
たとえば特定のドメインのhref
のみを抽出したい場合は、↓のように書くことも出来ます。
from bs4 import BeautifulSoup
import re
html = '''
<a href="https://red.com/i-am-red/">Red</a>
<a href="https://green.com/hello-green/">Green</a>
<a href="https://green.com/good-bye-green/">Green</a>
<a href="https://blue.com/i-am-blue/">Blue</a>
'''
soup = BeautifulSoup(html, 'html.parser')
links = soup.find_all('a', attrs={ 'href': re.compile(r'.*://green\.com/.*$') })
for link in links:
print(link.get('href'))
ドメインによるフィルタリングは1度要素を取得した後に行うこともできますが、↑のようにすればfind_all()
の段階でフィルタリングを行うことが出来ます。
おわりに
スクレイピングでHTML要素のhref
属性を取得したいケースは多いと思います。
BeautifulSoup4では簡単に取得が可能です。
🦝 < ところでhrefって「フレフ」でいいの?
🐭 < 「エイチレフ」じゃない?