beautifulsoup table 树:找到两个对象之间的所有 tr?
beautifulsoup table tree: find all tr between two objects?
嗨,我有 HTML table 这样的(代码中的注释自我解释):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<tbody>
<!-- there is a box -->
<tr>RED BOX</tr>
<!-- containing the following balls, each <td> has a ball -->
<!-- may be more than one <tr> -->
<tr>
<td>ball 1</td>
<td>ball 2</td>
</tr>
<tr>
<td>ball 3</td>
</tr>
<!-- another box -->
<tr>GREEN BOX</tr>
<!-- containing the following balls -->
<tr>
<td>ball 4</td>
</tr>
</tbody>
</body>
</html>
如代码中注释所示:RED BOX是一个tr
,球1、2、3在RED BOX中,由球1、2、3为在 tr
after <tr>RED BOX</tr>
中(球可能在一个或多个 tr
中)。 GREEN BOX是另一个tr
,球4在tr
之后。
我想找到每个盒子里的球。我可以通过
找到<tr>RED BOX</tr>
和<tr>GREEN BOX</tr>
tr_box = bs.findAll(text=[regex 'something BOX'])
我可以使用
找到下一个tr
for t in tr_box:
t[0].find_next('tr')
(可以找到球 1、2、4,但未找到球 3)
但是(1)有没有像find_between_objects
这样的东西可以找到<tr>RED BOX</tr>
和<tr>GREEN BOX</tr>
之间的所有tr
?或者一些将所有 tr
分成部分的函数,除以 <tr>RED BOX</tr>
和 <tr>GREEN BOX</tr>
?
(2)如何找到<tr>GREEN BOX</tr>
和table结尾之间的所有tr
</tbody>
?
谢谢
选项 1: find_next_siblings()
和 break
当您遇到带有 GREEN BOX
.
的行时
red_box = soup.find("tr", text="RED BOX")
for row in red_box.find_next_siblings("tr"):
if row.get_text(strip=True) == "GREEN BOX":
break
print([td.get_text(strip=True) for td in row.find_all("td")])
或者 itertools.takewhile()
如果你想更像 Pythonic 的话。
选项 2: a search function.
def filter_rows(tag):
return tag.name == "tr" and \
tag.find_previous_sibling("tr", text="RED BOX") and \
tag.find_next_sibling("tr", text="GREEN BOX")
for row in soup.find_all(filter_rows):
print([td.get_text(strip=True) for td in row.find_all("td")])
两个选项都会打印:
['ball 1', 'ball 2']
['ball 3']
(2) how to find all tr between GREEN BOX and the end of table ?
这只是:
green_box = soup.find("tr", text="GREEN BOX")
for row in green_box.find_next_siblings("tr"):
print([td.get_text(strip=True) for td in row.find_all("td")])
这里不用打断循环,find_next_siblings()
当没有其他匹配的兄弟姐妹时,自然会停止。
仅供参考,complete gist 此处。
如果您只想从 "boxes" 中获取 "balls",使用此方法可能更简单。找到所有 tr
,然后在 tr
中找到所有 td
:
for tr in soup.find_all('tr'):
for td in tr.find_all('td'):
print(td.text)
打印:
ball 1
ball 2
ball 3
ball 4
嗨,我有 HTML table 这样的(代码中的注释自我解释):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<tbody>
<!-- there is a box -->
<tr>RED BOX</tr>
<!-- containing the following balls, each <td> has a ball -->
<!-- may be more than one <tr> -->
<tr>
<td>ball 1</td>
<td>ball 2</td>
</tr>
<tr>
<td>ball 3</td>
</tr>
<!-- another box -->
<tr>GREEN BOX</tr>
<!-- containing the following balls -->
<tr>
<td>ball 4</td>
</tr>
</tbody>
</body>
</html>
如代码中注释所示:RED BOX是一个tr
,球1、2、3在RED BOX中,由球1、2、3为在 tr
after <tr>RED BOX</tr>
中(球可能在一个或多个 tr
中)。 GREEN BOX是另一个tr
,球4在tr
之后。
我想找到每个盒子里的球。我可以通过
找到<tr>RED BOX</tr>
和<tr>GREEN BOX</tr>
tr_box = bs.findAll(text=[regex 'something BOX'])
我可以使用
找到下一个tr
for t in tr_box:
t[0].find_next('tr')
(可以找到球 1、2、4,但未找到球 3)
但是(1)有没有像find_between_objects
这样的东西可以找到<tr>RED BOX</tr>
和<tr>GREEN BOX</tr>
之间的所有tr
?或者一些将所有 tr
分成部分的函数,除以 <tr>RED BOX</tr>
和 <tr>GREEN BOX</tr>
?
(2)如何找到<tr>GREEN BOX</tr>
和table结尾之间的所有tr
</tbody>
?
谢谢
选项 1: find_next_siblings()
和 break
当您遇到带有 GREEN BOX
.
red_box = soup.find("tr", text="RED BOX")
for row in red_box.find_next_siblings("tr"):
if row.get_text(strip=True) == "GREEN BOX":
break
print([td.get_text(strip=True) for td in row.find_all("td")])
或者 itertools.takewhile()
如果你想更像 Pythonic 的话。
选项 2: a search function.
def filter_rows(tag):
return tag.name == "tr" and \
tag.find_previous_sibling("tr", text="RED BOX") and \
tag.find_next_sibling("tr", text="GREEN BOX")
for row in soup.find_all(filter_rows):
print([td.get_text(strip=True) for td in row.find_all("td")])
两个选项都会打印:
['ball 1', 'ball 2']
['ball 3']
(2) how to find all tr between GREEN BOX and the end of table ?
这只是:
green_box = soup.find("tr", text="GREEN BOX")
for row in green_box.find_next_siblings("tr"):
print([td.get_text(strip=True) for td in row.find_all("td")])
这里不用打断循环,find_next_siblings()
当没有其他匹配的兄弟姐妹时,自然会停止。
仅供参考,complete gist 此处。
如果您只想从 "boxes" 中获取 "balls",使用此方法可能更简单。找到所有 tr
,然后在 tr
中找到所有 td
:
for tr in soup.find_all('tr'):
for td in tr.find_all('td'):
print(td.text)
打印:
ball 1
ball 2
ball 3
ball 4