📌
BeautifulSoupで特定の要素を選択するチートシート
主に以下のサイトを参考にさせていただきました。
インポート
from bs4 import BeautifulSoup
soupにHTMLの中身を入れる
# Requestsを利用して取り込む
res = requests.get('http://nenmatsunenshiha.com/')
soup = BeautifulSoup(res.text, 'html.parser')
# Seleniumを利用して取り込む
driver = webdriver.Chrome(driver_path, options=options)
driver.get('http://nenmatsunenshiha.com/')
html = driver.page_source
soup = BeautifulSoup(html, "html.parser")
基本的な文字列の取り出し方
コード | 動作 |
---|---|
soup.select("title")[0].string | titleタグの1番目の要素の中の文字列 |
soup.get_text() | 文字列すべて |
要素の選択の仕方(CSSセレクタを利用)
findやfind_allを利用するのも手なのですが、select系だとCSSセレクタというものを利用できるらしく、ほかにも応用が利きそうなのでこちらを利用しています。
すべてリストで返ってくるはずなので、利用するときは[0]のように何番目の要素なのか指定する必要があります。(select_oneを利用すれば話は別です)
コード | 指定内容 |
---|---|
soup.select("li") | タグがli |
soup.select("li, p") | タグがliまたはp |
soup.select('a[data]) | タグがaで、dataという属性を持っている |
soup.select('a[href="http://www.google.com"]') | タグがaで、href属性が"http://www.google.com" |
soup.select(".ramen") | クラスがramen |
soup.select("[class='ramen item']") | 完全一致('ramen item')。rowspanとかも使えるのでやりやすい。 |
soup.select(".ramen.item") | 部分一致、AND検索(classに'ramen', 'item'のそれぞれを含む) |
soup.select("li.favorite") | タグがliで、クラスにfavoriteを含む |
soup.select("#miso") | idがmiso |
soup.select("#miso, #tonkotsu") | idがmisoまたはidがtonkotsu |
soup.select('html body p') | タグの親子関係を指定 |
soup.body.select('p') | 上と同様の結果 |
soup.select('html > body') | 直接の親子関係 |
soup.select("ul#book > li") | 「idがbookのul」の子要素のli |
soup.select("p.title + p") | 直後の兄弟要素 |
soup.select("p.title ~ p") | 後ろすべての兄弟要素 |
おまけ:指定した要素が手に入るまでリトライしてくれる関数
Seleniumベースで作りました。
import time
import traceback
from bs4 import BeautifulSoup
def patient_selector(driver, url, css_selector, retry_count=12, sec_to_sleep=10) -> list:
"""css_selectorには`soup.select()`の中身を入れる。"""
for _ in range(retry_count):
try:
driver.get(url)
html = driver.page_source.encode('utf-8')
soup = BeautifulSoup(html, "html.parser")
# 指定した中身が入っていればreturn。Noneならもう一度。
result = soup.select(css_selector)
if result:
return result
print('Not desired html. Retrying.')
time.sleep(sec_to_sleep)
except Exception as e:
# 何かしらのエラーでももう一度
traceback.print_exc()
time.sleep(sec_to_sleep)
# リトライしてもダメだったなら空のリストを返す
return []
Discussion