beautifulsoup
配置要素
サーチ…
BeautifulSoupの要素の後にテキストを配置する
次のHTMLがあるとします。
<div>
<label>Name:</label>
John Smith
</div>
label
要素の後にテキスト「John Smith」を配置する必要があります。
この場合、 label
要素をテキストで検索し、 .next_sibling
プロパティを使用することが.next_sibling
ます 。
from bs4 import BeautifulSoup
data = """
<div>
<label>Name:</label>
John Smith
</div>
"""
soup = BeautifulSoup(data, "html.parser")
label = soup.find("label", text="Name:")
print(label.next_sibling.strip())
John Smith
印刷します。
CSSセレクタを使ってBeautifulSoupの要素を探す
BeautifulSoupはCSSセレクタのサポートが限られていますが、最も一般的に使用されています。 select()
メソッドを使用して複数の要素を検索し、 select_one()
を使用して単一の要素を検索します。
基本的な例:
from bs4 import BeautifulSoup
data = """
<ul>
<li class="item">item1</li>
<li class="item">item2</li>
<li class="item">item3</li>
</ul>
"""
soup = BeautifulSoup(data, "html.parser")
for item in soup.select("li.item"):
print(item.get_text())
印刷物:
item1
item2
item3
コメントの検索
コメントを見つけるにはBeautifulSoup
使用し、 text
(またはstring
であることをタイプをチェックする最近のバージョンでは)引数をComment
:
from bs4 import BeautifulSoup
from bs4 import Comment
data = """
<html>
<body>
<div>
<!-- desired text -->
</div>
</body>
</html>
"""
soup = BeautifulSoup(data, "html.parser")
comment = soup.find(text=lambda text: isinstance(text, Comment))
print(comment)
desired text
印刷しdesired text
。
フィルタ関数
BeautifulSoupでは、 find_all
などの関数に関数を提供することで、結果をフィルタリングできます。これは、コードの再利用のためのツールだけでなく、複雑なフィルタにも役立ちます。
基本的な使用法
唯一の引数として要素をとる関数を定義します。引数が一致する場合、関数はTrue
を返しTrue
。
def has_href(tag):
'''Returns True for tags with a href attribute'''
return bool(tag.get("href"))
soup.find_all(has_href) #find all elements with a href attribute
#equivilent using lambda:
soup.find_all(lambda tag: bool(tag.get("href")))
もう1つの例では、 href
値が
フィルタ関数への追加引数の提供
find_all
渡される関数は引数を1つしか取ることができないので、関数を生成する関数ファクトリをfind_all
で使用するのに適しているとfind_all
ます。これは、タグ検出機能をより柔軟にするために役立ちます。
def present_in_href(check_string):
return lambda tag: tag.get("href") and check_string in tag.get("href")
soup.find_all(present_in_href("/partial/path"))
最初に選択したタグの内部タグとその属性へのアクセス
soup.find('div', class_='base class')
選択した後にhtml
があるとしましょう:
from bs4 import BeautifulSoup
soup = BeautifulSoup(SomePage, 'lxml')
html = soup.find('div', class_='base class')
print(html)
<div class="base class">
<div>Sample text 1</div>
<div>Sample text 2</div>
<div>
<a class="ordinary link" href="https://example.com">URL text</a>
</div>
</div>
<div class="Confusing class"></div>
'''
また、 <a>
タグのhref
にアクセスするには、次のようにします。
a_tag = html.a
link = a_tag['href']
print(link)
https://example.com
これは、 attrs
があなたに一意のIDを与えないので、 <a>
タグを直接選択することができない場合に便利です。解析されたページに他の "twin" <a>
タグがあります。しかし、必要な<a>
を含む親タグを一意に選択することができます。
一連のページからオプションの要素および/またはその属性を収集する
あなたがページ数を解析し、恥ずかしそうなページのためにオプションである (あるページに提示することができ、別のページに存在させることができる)要素から値を収集したいという状況を考えてみましょう。
さらに、たとえば、要素そのものはページ上で最も普通の要素です。つまり、特定の属性で一意に特定することはできません。しかし、親要素を適切に選択でき、それぞれの入れ子レベルで要素の順序番号を知っていることがわかります。
from bs4 import BeautifulSoup
soup = BeautifulSoup(SomePage, 'lxml')
html = soup.find('div', class_='base class') # Below it refers to html_1 and html_2
必要な要素はオプションなので、 html
には2つの状況があります:
html_1 = '''
<div class="base class"> # №0
<div>Sample text 1</div> # №1
<div>Sample text 2</div> # №2
<div>!Needed text!</div> # №3
</div>
<div>Confusing div text</div> # №4
'''
html_2 = '''
<div class="base class"> # №0
<div>Sample text 1</div> # №1
<div>Sample text 2</div> # №2
</div>
<div>Confusing div text</div> # №4
'''
あなたがhtml_1
を手にhtml_1
たら、収集することができます!Needed text!
タグ№3からこのように:
wanted tag = html_1.div.find_next_sibling().find_next_sibling() # this gives you whole tag №3
当初は№1取得div
次に、その後、2回スイッチをdiv
№3に到達するために、同じ入れ子レベルで。
wanted_text = wanted_tag.text # extracting !Needed text!
このアプローチの有用性は、 html_2
を取得したときに発生します。アプローチによってエラーが発生することはありNone
。
print(html_2.div.find_next_sibling().find_next_sibling())
None
ここでfind_next_sibling()
を使うことは、それぞれのネストレベルで要素の検索を制限するため、重要です。 find_next find_next()
使用する場合は、タグ№4が収集され、あなたはそれを望んでいません:
print(html_2.div.find_next().find_next())
<div>Confusing div text</div>
また、 find_previous_sibling()
とfind_previous()
を逆の方法で探索することもできます。
すべて記載されている機能は、すべてのタグだけではなく、最初のものをキャッチするために彼らのmiltipleバリアントを持っています。
find_next_siblings()
find_previous_siblings()
find_all_next()
find_all_previous()