Вы делаете неправильно, потому что:
th_node = soup.find('th', { 'scope' : 'row' }, text = re.compile('^Fruits'))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
От this answer:
Вам нужно будет использовать гибридный подход, поскольку text=
потерпит неудачу, когда элемент имеет дочерние элементы, а также текст.
И, например:
>>> a = '<th scope="row">foo</th>'
>>> b = '<th scope="row">foo<td>bar</td></th>'
>>> BeautifulSoup(a, "html.parser").find('th', {'scope': 'row'}, text='foo')
<th scope="row">foo</th>
>>> BeautifulSoup(b, "html.parser").find('th', {'scope': 'row'}, text='foo')
>>> BeautifulSoup(b, "html.parser").find('th', {'scope': 'row'}, text='foobar')
Престол, BeautifulSoup потерпели неудачу, когда есть td
тег в th
тег. Так что нам нужно (идея также от этого ответа):
html = """
<th scope="row">Fruits<br />
<i><a href="#Fruits">Buy</a></i></th>
<td><a href="banana.html" color="yellow">Banana</a><br />
<a href="kiwi.html" color="green">Kiwi</a><br />
<a href="Persimmon" color="orange">Persimmon</a><br />
</tr>
"""
import re
from bs4 import BeautifulSoup
soup = BeautifulSoup(html)
reg = re.compile(r'^Fruits')
th_node = [e for e in soup.find_all(
'th', {'scope': 'row'}) if reg.search(e.text)][0]
print th_node
Выход:
<th scope="row">Fruits<br/>
<i><a href="#Fruits">Buy</a></i></th>
Да, это вы не хотите, потому что td
тег не внутри th
тега. Так что теперь мы можем использовать tag.find_next()
метод как это:
html = """
<th scope="row">Fruits<br />
<i><a href="#Fruits">Buy</a></i></th>
<td><a href="banana.html" color="yellow">Banana</a><br />
<a href="kiwi.html" color="green">Kiwi</a><br />
<a href="Persimmon" color="orange">Persimmon</a><br />
</tr>
"""
import re
from bs4 import BeautifulSoup
soup = BeautifulSoup(html)
reg = re.compile(r'^Fruits')
th_node = [e for e in soup.find_all(
'th', {'scope': 'row'}) if reg.search(e.text)][0]
td_node = th_node.find_next('td')
fruits = td_node.find_all('a')
for f in fruits:
print f['color'], " ", f.text
Выход:
yellow Banana
green Kiwi
orange Persimmon
Тогда мы сделали!