beautifulsoup4==4.12.3 で動作確認しています。
まとめ
-
bs4.element.Tagオブジェクトxに対し、x[attr_name]は「xの属性attr_nameの値」、y in xは「HTML 要素yがx直下にあるか」を意味する。- 直感に反して
[]とinで適用対象のメンバが異なる。x[attr_name]で属性が取れるからといってattr_name in xで属性の有無を判定するのは誤りなので注意する。
- 直感に反して
スニペット
from bs4 import BeautifulSoup
text = '<div id="hoge"><p>Apple</p>Banana</div>'
soup = BeautifulSoup(text, 'html.parser')
div = soup.find('div')
p = soup.find('p')
# 1
assert div['id'] == 'hoge'
# 2
assert 'id' not in div
# 3
assert 'id' in div.attrs
assert type(div.attrs) is dict
# 4
assert p in div
assert 'Apple' not in div
assert 'Banana' in div
assert type(div.contents) is list
-
bs4.element.Tagオブジェクトは角括弧で属性にアクセスできる。 - じゃあ
in演算子で属性の有無を判定できるかというとできない。 - 属性の有無を判定するには
.attrsメンバにin演算子を適用する (.attrsメンバからそのタグの属性の辞書にアクセスできる)。 -
bs4.element.Tagオブジェクトに直接in演算子を適用したときに判定できるのは直下の要素の有無である (in演算子は直下の要素のリスト.contentsに対するinとして実装されているため)。