2013-11-25 44 views
2

我有一個關於使用其子項屬性之一的條件來選擇標籤列表(或單個標籤)的問題。具體地,給出的HTML代碼:根據美麗的湯中兒童的文本值查找標籤列表

<tbody> 
<tr class="" data-row="0"> 
<tr class="" data-row="1"> 
<tr class="" data-row="2"> 
    <td align="right" csk="13">13</td> 
    <td align="left" csk="Jones,Andre"><a href="/players/andre-jones-2.html">Andre Jones</a>  
    </td> 
<tr class="" data-row="3"> 
    <td align="right" csk="7">7</td> 
    <td align="left" csk="Jones,DeAndre"><a href="/players/deandre-jones-1.html">DeAndre Jones</a> 
    </td> 
<tr class="" data-row="4"> 
<tr class="" data-row="5"> 

我有一個Unicode變量從外部環路來了,我想通過每行看在表Player==Table.tr.a.text提取<tr>標籤和識別重複的球員名字Table。因此,舉例來說,如果有多於一名玩家Player=Andre Jones,MyRow對象返回包含該玩家名稱的所有<tr>標籤,而如果只有一行Player=Andre Jones,那麼MyRow僅包含具有等於錨文本屬性的單個元素<tr>Andre Jones。我一直在努力的事情像

Table = soup.find('tbody') 
MyRow = Table.find_all(lambda X: X.name=='tr' and Player == X.text) 

但這返回[]MyRow。如果我使用

MyRow = Table.find_all(lambda X: X.name=='tr' and Player in X.text) 

這將挑選具有PlayerX.text一個子任何<tr>。在上面的示例代碼中,它提取了<tr>標籤與Table.tr.td.a.text=='Andre Jones'Table.tr.td.a.text=='DeAndre Jones'。任何幫助,將不勝感激。

回答

0

無論你的願望。 :)

解決方法1

邏輯:找到的第一個標籤,其標籤名稱爲TR,幷包含「FooName」在這個標籤中的文本,包括它的孩子。

# Exact Match (text is unicode, turn into str) 
print Table.find(lambda tag: tag.name=='tr' and 'FooName' == tag.text.encode('utf-8')) 
# Fuzzy Match 
# print Table.find(lambda tag: tag.name=='tr' and 'FooName' in tag.text) 

輸出:

<tr class="" data-row="2"> 
<td align="right" csk="3">3</td> 
<td align="left" csk="Wentz,Parker"> 
<a href="/players/Foo-Name-1.html">FooName</a> 
</td> 
</tr> 

溶液2

邏輯:找到其文本包含FooName元素,在這種情況下anchor標籤。然後去了樹,並搜索其所有家長(包括祖先),它的標記名稱是tr

# Exact Match 
print Table.find(text='FooName').find_parent('tr') 
# Fuzzy Match 
# import re 
# print Table.find(text=re.compile('FooName')).find_parent('tr') 

輸出

<tr class="" data-row="2"> 
<td align="right" csk="3">3</td> 
<td align="left" csk="Wentz,Parker"> 
<a href="/players/Foo-Name-1.html">FooName</a> 
</td> 
</tr> 
+0

太好了!非常感謝你的幫助。 –

+0

@MarkClements請標記最能幫助您的答案,以便其他人可以輕鬆搜索。 –

+0

代碼似乎是匹配首字母或姓氏,而不是整個名稱。因此,它不僅將「安德烈瓊斯」和「德安德魯瓊斯」視爲相同,還包括「特倫斯」和「特倫斯薩爾斯伯裏」。 –

2

您可以用XPath和LXML做到這一點很容易:

import lxml.html 

root = lxml.html.fromstring('''...''') 
td = root.xpath('//tr[.//a[text() = "FooName"]]') 

BeautifulSoup「等效」將類似於:

rows = soup.find('tbody').find_all('tr') 
td = next(row for row in rows if row.find('a', text='FooName')) 

或者,如果你向後想一想:

td = soup.find('a', text='FooName').find_parent('tr') 
+0

我還沒有學過lxml,但是感謝BS解決方案。 –

+0

你提供的美麗的湯碼只會給我第一次出現'text ='FooName''。我已經完善了我的問題,以更具體地瞭解我在找什麼。謝謝你的幫助。 –

+0

@MarkClements:那麼XPath表達式就可以工作了。 – Blender