Magicode logo
Magicode
1
4 min read

BeautifulSoupで特定の要素を選択するチートシート

https://cdn.apollon.ai/media/notebox/blob_VnZCUjb
主に以下のサイトを参考にさせていただきました。

インポート

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].stringtitleタグの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

コメントにはログインが必要です。