特定の属性のみを持つタグを見つける方法-BeautifulSoup


84

BeautifulSoupを使用して、検索した属性のみを含むタグを検索するにはどうすればよいですか?

たとえば、すべての<td valign="top">タグを検索したいとします。

次のコード: raw_card_data = soup.fetch('td', {'valign':re.compile('top')})

必要なすべてのデータを取得<td>しますが、属性を持つタグも取得しますvalign:top

私も試しました: raw_card_data = soup.findAll(re.compile('<td valign="top">')) そしてこれは何も返しません(おそらく正規表現が悪いため)

BeautifulSoupに「<td>属性が唯一のタグを探す」と言う方法があるのではないかと思っていましたvalign:top

たとえば、HTMLドキュメントに次の<td>タグが含まれている場合の更新

<td valign="top">.....</td><br />
<td width="580" valign="top">.......</td><br />
<td>.....</td><br />

最初の<td>タグ(<td width="580" valign="top">)だけを返したい

回答:


96

BeutifulSoupのドキュメントで説明されているように

あなたはこれを使うことができます:

soup = BeautifulSoup(html)
results = soup.findAll("td", {"valign" : "top"})

編集:

valign = "top"属性のみを持つタグを返すには、タグattrsプロパティの長さを確認できます。

from BeautifulSoup import BeautifulSoup

html = '<td valign="top">.....</td>\
        <td width="580" valign="top">.......</td>\
        <td>.....</td>'

soup = BeautifulSoup(html)
results = soup.findAll("td", {"valign" : "top"})

for result in results :
    if len(result.attrs) == 1 :
        print result

それは戻ります:

<td valign="top">.....</td>

julio.alegriaへの私のコメントによると、これは他の属性を<tr>持つタグをvalign="top"含む、属性を持つすべてのタグを検索します(<td width="580" valign="top">この検索で​​も返されます)私は<tr>唯一の属性がvalign="top"
Snaxib Jan19

したがって、len(tag.attrs)を確認できます。(tag.attrs)lenの場合> 1、(私は私のポストを編集した)タグを無視する
ロイック・G.

51

ドキュメントで説明さlambdafindAllているように、で関数を使用できます。そのため、あなたの場合、以下を使用するだけでタグを検索します。tdvalign = "top"

td_tag_list = soup.findAll(
                lambda tag:tag.name == "td" and
                len(tag.attrs) == 1 and
                tag["valign"] == "top")

4
BSのフルパワーを使用しているため、ベストアンサー
Rafael T

2
それはあなたに非常に最適化された方法で結果を与えるので素晴らしい答え。
CrazyGeek 2015年

32

任意の値の属性名のみで検索する場合

from bs4 import BeautifulSoup
import re

soup= BeautifulSoup(html.text,'lxml')
results = soup.findAll("td", {"valign" : re.compile(r".*")})

Steve Lorimerによると、正規表現ではなくTrueを渡す方がよい

results = soup.findAll("td", {"valign" : True})

2
の後r".*"に括弧がないため、コンパイルされません。
ジャックコール

9
正規表現のための必要はありません、ただ渡すんTrueresults = soup.findAll("td", {"valign" : True})
スティーブ・ロリマー

14

これを行う最も簡単な方法は、新しいCSSスタイルのselect方法を使用することです。

soup = BeautifulSoup(html)
results = soup.select('td[valign="top"]')

4

の引数として渡すだけですfindAll

>>> from BeautifulSoup import BeautifulSoup
>>> soup = BeautifulSoup("""
... <html>
... <head><title>My Title!</title></head>
... <body><table>
... <tr><td>First!</td>
... <td valign="top">Second!</td></tr>
... </table></body><html>
... """)
>>>
>>> soup.findAll('td')
[<td>First!</td>, <td valign="top">Second!</td>]
>>>
>>> soup.findAll('td', valign='top')
[<td valign="top">Second!</td>]

1
そのようなタグがある場合はどうなります<td width="580" valign="top">か?私はそれらを取得したくありません。唯一の属性がvalign="top"
Snaxib 2012年

2

Chris RedfordとAmrの回答の組み合わせを追加すると、selectコマンドを使用して任意の値の属性名を検索することもできます。

from bs4 import BeautifulSoup as Soup
html = '<td valign="top">.....</td>\
    <td width="580" valign="top">.......</td>\
    <td>.....</td>'
soup = Soup(html, 'lxml')
results = soup.select('td[valign]')

同じ方法を試しましたが、これは機能しません。回避策はありますか?
Phaneendra CharyuluKanduri19年

1
@PhaneendraCharyuluKanduri申し訳ありませんが、コードに不正なコーディングエラーがありました。これで、コピーと貼り付けが機能するはずです。
GrazingScientist
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.