簡単な質問があります:
BeautifulSoupを使用してWebサイトの特定の部分をスクレイピングするには、data.find()
、data.findAll()
またはdata.select()
。
質問は次のとおりです。 .find()
メソッドと.select()
メソッドの間に大きな違いはありますか? (例:パフォーマンスまたは柔軟性、または...)
またはそれらは同じですか?
敬具
コメントを要約するには:
soup.select("div[id=foo] > div > div > div[class=fee] > span > span > a")
は複数のチェーンfind/find_all呼び出しを使用するとかなり見苦しくなります。find("a", href=re.compile(....))
よりもはるかに良いと思いますが、これも個人的なものです好み。パフォーマンスのために、いくつかのテストを実行できます。 here here から取得した800以上のhtmlファイルで実行する answer here からコードを変更しましたが、網羅的ではありませんが、一部のオプションの読みやすさとパフォーマンス:
変更された機能は次のとおりです。
from bs4 import BeautifulSoup
from glob import iglob
def parse_find(soup):
author = soup.find("h4", class_="h12 talk-link__speaker").text
title = soup.find("h4", class_="h9 m5").text
date = soup.find("span", class_="meta__val").text.strip()
soup.find("footer",class_="footer").find_previous("data", {
"class": "talk-transcript__para__time"}).text.split(":")
soup.find_all("span",class_="talk-transcript__fragment")
def parse_select(soup):
author = soup.select_one("h4.h12.talk-link__speaker").text
title = soup.select_one("h4.h9.m5").text
date = soup.select_one("span.meta__val").text.strip()
soup.select_one("footer.footer").find_previous("data", {
"class": "talk-transcript__para__time"}).text
soup.select("span.talk-transcript__fragment")
def test(patt, func):
for html in iglob(patt):
with open(html) as f:
func(BeautifulSoup(f, "lxml")
タイミングについては:
In [7]: from testing import test, parse_find, parse_select
In [8]: timeit test("./talks/*.html",parse_find)
1 loops, best of 3: 51.9 s per loop
In [9]: timeit test("./talks/*.html",parse_select)
1 loops, best of 3: 32.7 s per loop
網羅的ではないと言ったように、cssセレクターは間違いなくより効率的であると言えます。