Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 根据Beautiful Soup中儿童的文本值查找标记列表_Python_Python 2.7_Beautifulsoup - Fatal编程技术网

Python 根据Beautiful Soup中儿童的文本值查找标记列表

Python 根据Beautiful Soup中儿童的文本值查找标记列表,python,python-2.7,beautifulsoup,Python,Python 2.7,Beautifulsoup,我有一个关于选择标签列表或单个标签的问题,使用它的子属性之一的条件。具体来说,给定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,An

我有一个关于选择标签列表或单个标签的问题,使用它的子属性之一的条件。具体来说,给定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">
但这会为MyRow返回[]。如果我使用

MyRow = Table.find_all(lambda X: X.name=='tr' and Player in X.text)
这将选择任何将Player作为X.text子字符串的。在上面的示例代码中,它使用Table.tr.td.a.text=='Andre Jones'和Table.tr.td.a.text=='DeAndre Jones'提取两个标记。任何帮助都将不胜感激。

无论你想要什么:

解决方案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>
输出

<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>
你想要什么都行

解决方案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>
输出

<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>

使用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')

使用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')

伟大的非常感谢您的帮助。@MarkClements请将对您最有帮助的答案标记为已接受,以便其他人搜索。代码似乎匹配的是姓名,而不是全名。因此,它不仅将安德烈·琼斯和迪安德尔·琼斯视为同一个人,还将特伦斯和特伦斯·索尔斯贝里视为同一个人。我在使用解决方案1或解决方案2时遇到了一个问题。我有两个名字安德烈·琼斯和迪安德尔·琼斯在两行不同的文本属性中。然而,代码只选择了带有DeAndre Jones的标签。我可以看到这一点,因为如果我在解决方案1中使用find_all和Player=Andre Jones,它将返回一个包含两个元素的列表:带有文本Andre Jones和DeAndre Jones的标记。但是,如果Player=DeAndre-Jones,代码将返回一个包含单个元素的列表:带有文本DeAndre-Jones的标记。“我搞不懂这里发生了什么事。@MarkClements我对旧逻辑进行了注释,并将完全匹配的解决方案放在那里。我使用模糊匹配,它试图找到包含fooname的标记,这就是为什么它为您返回多条记录。如果您有进一步的名称匹配问题,比如使用我注释掉的正则表达式方法,您需要自定义我编写的函数以满足您的口味。太棒了!非常感谢您的帮助。@MarkClements请将对您最有帮助的答案标记为已接受,以便其他人搜索。代码似乎匹配的是姓名,而不是全名。因此,它不仅将安德烈·琼斯和迪安德尔·琼斯视为同一个人,还将特伦斯和特伦斯·索尔斯贝里视为同一个人。我在使用解决方案1或解决方案2时遇到了一个问题。我有两个名字安德烈·琼斯和迪安德尔·琼斯在两行不同的文本属性中。然而,代码只选择了带有DeAndre Jones的标签。我可以看到这一点,因为如果我在解决方案1中使用find_all和Player=Andre Jones,它将返回一个包含两个元素的列表:带有文本Andre Jones和DeAndre Jones的标记。但是,如果Player=DeAndre-Jones,代码将返回一个包含单个元素的列表:带有文本DeAndre-Jones的标记。“我搞不懂这里发生了什么事。@MarkClements我对旧逻辑进行了注释,并将完全匹配的解决方案放在那里。我使用模糊匹配,它试图找到包含fooname的标记,这就是为什么它为您返回多条记录。如果您有进一步的名称匹配问题,比如使用我注释掉的正则表达式方法,您需要自定义我编写的函数以满足您的口味。您提供的漂亮的soup代码只会给我第一次出现的text='FooName'。我已经将我的问题细化为更具体的我在寻找什么。谢谢你的帮助。你提供的漂亮的汤代码只会给我第一次出现的地方text='foodname'。我已经将我的问题细化为更具体的我在寻找什么。谢谢你的帮助。