Python: BeautifulSoup 使い方(タイトル・HTML 取得など)

BeautifulSoup モジュール は、HTML や XML ファイルからタイトルやヘディングを取得することができるモジュールである。正規表現を組み合わせれば、様々な情報を整形して取得することが可能である。
エンジニア速報は Twitter の@commteで配信しています。
BeautifulSoup モジュールのポイント
- HTML から要素を取得出力する
- html タグは除去可能
- 深い階層の要素まで絞り込みできる
pip install beautifulsoup4
ドキュメント:Beautiful Soup 4.9.0 documentation
基本の形
find() メソッドの引数に条件を指定することで、html のタグを取得することができる。Tag は BeautifulSoup の Tag オブジェクトのことである。
# Tag オブジェクトを返す
soup.find("タグ")
# 指定した属性に一致するTagオブジェクトを返す
soup.find(属性=属性値)
# 指定したタグと属性に一致するTagオブジェクトを返す
soup.find("タグ", 属性=属性値)
# Tag のシーケンス
soup.find_all("タグ")
# タグの名前
Tag.name
# タグの中のテキスト
Tag.text
# 属性の値
Tag.get("属性名")
使用例
print(soup.p)
# <p class="text_en">Lorem ipsum dolor sit amet consequat.</p>
print(soup.a)
# <a class="underline" href="#">これはダミーリンクです。</a>
find メソッド
次は、変数 html_doc に、ダミー HTML を格納し、find メソッドによって p タグの中身を取得する例である。
html_doc = """
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>HTML Document Template</title>
<meta name="description" content="これはhtmlのテンプレートです。">
<meta name="keywords" content="html, template">
</head>
<body>
<h1>h1 heading</h1>
<article>
<header>
<h2>h2 heading</h2>
<p class="text_en">Lorem ipsum dolor sit amet consequat.</p>
<ul>
<li>list 1</li>
<li>list 2</li>
<li>list 3</li>
</ul>
</header>
<section>
<h3>h3 heading</h3>
<p class="text_jp">親譲りの無鉄砲で小供の時から損ばかりしている。</p>
<a href="#" class="underline">これはダミーリンクです。</a>
<figure>
<img src="https://dummyimage.com/600x400/000/fff" alt="">
<figcaption>
<p>上の画像はダミーです。</p>
</figcaption>
</figure>
</section>
</article>
</body>
</html>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc)
print(soup.find("p"))
# <p class="text_en">Lorem ipsum dolor sit amet consequat.</p>
.find()メソッドで、タグを指定して取得することができる。
.get_text() メソッドを付与すると、html タグを除去したテキストのみ抽出することができる。タイトルだけなら、.title.string でも取得可能。
次のコードは、メタタグタイトルのテキストを取得した。
print(soup.find("title").get_text())
# HTML Document Template
print(soup.title.string)
# TML Document Template
head
head の中のメタタグ(タイトル、ディスクリプション、キーワード等)を取得する。
print(soup.head)
# <head>
# <meta charset="utf-8"/>
# <title>HTML Document Template</title>
# <meta content="これはhtmlのテンプレートです。" name="description"/>
# <meta content="html, template" name="keywords"/>
# </head>
絞り込み
ドットで連結させることで任意の場所を絞り込む。次のコードは「section > figure > figcaption > p」まで絞り込んで取得している。
print(soup.section.figure.figcaption.p)
# <p>上の画像はダミーです。</p>
子要素
子要素をリストに格納する。.contents は、ul の中に入っている li をリストに格納する。
print(soup.header.ul.contents)
# ['\n', <li>list 1</li>, '\n', <li>list 2</li>, '\n', <li>list 3</li>, '\n']
親要素
親要素取得。
print(soup.title.parent.name)
# head
print(soup.li.parent.name)
# ul
CSS クラス属性
クラス名取得。
print(soup.p['class'])
# ['text_en']
class 属性の値を元に検索。class は Python の予約語なので、アンダーバー をつける。id をたどる場合は、アンダーバーは不要。
print(soup.find_all("p", class_="text_jp"))
# [<p class="text_jp">親譲りの無鉄砲で小供の時から損ばかりしている。</p>]
print(soup.find("div", id="content"))
タグ除去
get_text() メソッドはタグを除去する。空白と改行は除去されない。
print(soup.get_text())
# html タグ除去
タグと空白と改行とタグを除去。.stripped_strings ジェネレーターは、空白を除くことができる
for string in soup.stripped_strings:
print(repr(string))
# 'HTML Document Template'
# 'h1 heading'
# 'h2 heading'
目的の要素
strip=True をセットすれば、目的の属性のテキストのみ取得可能。
# body の 文字だけ取得
print(soup.find('body').get_text(strip=True))
# h1 headingh2 headingLorem ipsum dolor ...
正規表現
次のコードは、正規表現を使って、「f」で始まる html タグを取得している。find_all は、引数に一致する 全ての 属性を見つける。
import re
for i in soup.find_all(re.compile("^f")):
print(i.name)
# figure
# figcaption
取得数
limit 引数 は、取得する数を指定できる。
print(soup.find_all("li", limit=2))
# [<li>list 1</li>, <li>list 2</li>]
任意のサイトをスクレイピングする
requests と BeautifulSoup モジュール をインポートし、外部サイトの様々な情報を同時に取得する。
# Requests ----------------
import requests
r = requests.get("https://httpbin.org/")
print(f"ステータスコード = {r.status_code}")
print(f"エンコーディング = {r.encoding}")
print(f"コンテンツのタイプ = {r.headers['content-type']}")
print(f"コンテンツの長さ = {r.headers['Content-Length']}")
html = r.text
# html の最初の100文字まで表示
print(f"{html[0:100]}")
# BeautifulSoup -----------
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# タイトル取得
print(f"タイトル = {soup.title.string}")
# h2取得
print(f"h2 = {soup.h2}")
上の結果。様々な情報を取得することができた。
ステータスコード = 200
エンコーディング = utf-8
コンテンツのタイプ = text/html; charset=utf-8
コンテンツの長さ = 9593
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>httpbin.org</title>
タイトル = httpbin.org
h2 = <h2 class="title">httpbin.org
<small>
<pre class="version">0.9.2</pre>
</small>
</h2>
Python おすすめ本
スポンサード リンク
関連記事
- Python : 再帰は大きな問題が小さな問題に収束するように使う
- Python: f-string(f 文字列)と「:」の便利な使い方
- Python: bytes 型 と str 型の違い。変換方法
- Python: MySQL へ接続するモジュール mysqlclient(MySQLdb)の使い方
- Python: インポートしたときに「ModuleNotFoundError」になる場合の対処法
- Python: カウンタ。Counter()関数で要素数を計算する
- Python: Requests-HTML の使い方
- Python: Requests モジュールの使い方(スクレイピング、データ収集など)
- Python: SQL の基本コマンドと sqlite3 モジュール
- Python: JSON とは何か?(loads、dumps など)
Leave a Comment