web-dev-qa-db-ja.com

オブジェクトに他のクラスがある場合、BeautifulSoupはCSSクラスを見つけることができません

ページに_<div class="class1">_と_<p class="class1">_がある場合、soup.findAll(True, 'class1')は両方を検索します。

ただし、_<p class="class1 class2">_がある場合は、見つかりません。他のクラスがあるかどうかに関係なく、特定のクラスを持つすべてのオブジェクトを見つけるにはどうすればよいですか?

40
endolith

誰かがこの質問に出くわした場合に備えて。 BeautifulSoupはこれをサポートするようになりました:

Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

In [1]: import bs4

In [2]: soup = bs4.BeautifulSoup('<div class="foo bar"></div>')

In [3]: soup(attrs={'class': 'bar'})
Out[3]: [<div class="foo bar"></div>]

また、findAllと入力する必要はもうありません。

19
Kugel

残念ながら、BeautifulSoupはこれをスペースを含むクラスとして扱います'class1 class2'2つのクラスではなく['class1','class2']。回避策は、文字列の代わりに正規表現を使用してクラスを検索することです。

これは機能します:

soup.findAll(True, {'class': re.compile(r'\bclass1\b')})
35
endolith

lxml を使用する必要があります。スペースで区切られた複数のクラス値( 'class1 class2')で機能します。

その名前にもかかわらず、lxmlはHTMLの解析とスクレイピングにも使用されます。これはBeautifulSoupよりもはるかに高速であり、BeautifulSoup(彼らの名声)よりも「壊れた」HTMLをより適切に処理します。 lxml APIを学びたくない場合は、BeautifulSoupの互換性APIもあります。

Ian Bickingは同意します そしてBeautifulSoupよりもlxmlを好みます。

Google App Engineを使用している場合、または純粋にPython)が許可されていないものを使用している場合を除いて、BeautifulSoupを使用する理由はもうありません。

LxmlでCSSセレクターを使用することもできるため、BeautifulSoupよりもはるかに簡単に使用できます。インタラクティブなPythonコンソールで試してみてください。

11
aehlke

特定のCSSクラスを持つタグを検索すると非常に便利ですが、CSS属性の名前「class」はPythonで予約されたWordです。クラスをキーワード引数として使用すると、構文エラーが発生します。 Beautiful Soup 4.1.2以降、キーワード引数class_を使用してCSSクラスで検索できます。

Like:

soup.find_all("a", class_="class1")
2
alan_wang