2017-12-14 24 views
1

で親要素の最初の子を取得するI次のHTMLを持っている:パイソン - BeautifulSoup4

<table id="mytable"> 
    <tr role="row"> 
     <td>abc1</td> 
     <td>abc2</td> 
     <td>abc3</td> 
     <td class="hm">Data1</td> 
     <td>Data2</td> 
     <td class="hm">no</td> 
     <td class="hx">yes</td> 
     <td class="hm">Updated</td> 
    </tr> 
    <tr role="row"> 
     <td>def1</td> 
     <td>def2</td> 
     <td>def3</td> 
     <td class="hm">Data3</td> 
     <td>Data4</td> 
     <td class="hm">no</td> 
     <td class="hx">no</td> 
     <td class="hm">Updated</td> 
    </tr> 
    <tr role="row"> 
     <td>hij1</td> 
     <td>hij2</td> 
     <td>hij3</td> 
     <td class="hm">Data5</td> 
     <td>Data6</td> 
     <td class="hm">no</td> 
     <td class="hx">no</td> 
     <td class="hm">Updated</td> 
    </tr> 
    <tr role="row"> 
     <td>klm1</td> 
     <td>klm2</td> 
     <td>klm3</td> 
     <td class="hm">Data7</td> 
     <td>Data8</td> 
     <td class="hm">no</td> 
     <td class="hx">yes</td> 
     <td class="hm">Updated</td> 
    </tr> 
</table> 

私は子供<td>がある場合1を検索するには、次のやっているように、これらの<tr>タグの倍数があります。 class="hx"とタグとyesのテキスト:

if (Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'})): 
    print "Found 'yes'" 

しかし、私が発見された<tr>の最初の<td>タグに興味があります。私は次のことをやってみましたが、動作するようには思えない。また

print Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).parent.find('td')[0].text 

、以下の作品が、私がわからない場合は特に、これを行うのは本当に引き出す方法のように思える何<td>タグ2人の間に存在します:

print Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).previousSibling.previousSibling.previousSibling.previousSibling.previousSibling.previousSibling.text 

もっと良い方法がありますか?何か不足していますか?

+1

スローされますか? – RomanPerekhrest

+0

'.previousSibling'のすべての作業で2番目の' print'が正しいですが、述べたように、他の '​​'タグが私が見つけたタグと最初のタグの間にいくつあるかはわかりません。 – rjbogz

+0

もちろん、私はそれを更新しましたが、 'find( 'td'、text = 'yes'、attrs = {'class': 'hx'})'の最初のインスタンスが必要です。だから 'abc1'と' klm1'ではなく 'abc1'だけをここに書いてください。 – rjbogz

答えて

3
あなたの第二の印刷の変更で

find('td')[0] 

へ:

find('td') 

検索は、最初の要素を返していないので、インデックスに必要。

from bs4 import BeautifulSoup 

text = """ 
<html><head><title>Foo</title></head> 
<body> 
<table id="mytable"> 
<tr role="row"> 
    <td>Col1</td> 
    <td>Col2</td> 
    <td>Col3</td> 
    <td class="hm">Data1</td> 
    <td>Data2</td> 
    <td class="hm">no</td> 
    <td class="hx">yes</td> 
    <td class="hm">Updated</td> 
</tr> 
<table> 
""" 
Soup = BeautifulSoup(text, 'html.parser') 

# Will raise error 
# print Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).find_parent().find('td')[0].text 

print Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).find_parent().find('td').text 

編集

find_all('td')に第2の列の変更find('td')を取得します。これは、リストを返しますので、あなたが行うことができます明らかに

td_data = Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).find_parent().find_all('td') 
print td_data[0].text # 1st column 
print td_data[1].text # 2nd column 

len(td_data) - 1より大きいあなたのインデックスは、それはあなたが `Col1`が最後に印刷したいのでIndexError

+0

次に2番目のカラムを取得するのはどうですか?さあ、私は 'abc1'と' abc2'の両方が必要です。編集: 'find( 'td')を実行します。nextSiblingは' abc2'のトリックを行うようです。 – rjbogz

+0

私の編集を参照してください。 'find_all'に変更すると、各列にインデックスを付けることができます。 – Harpal

+0

申し訳ありませんが、編集前の私の例では、今は固定 – Harpal