鉴于以下内容(从较大的文档中简化)
<tr class="row-class">
<td>Age</td>
<td>16</td>
</tr>
<tr class="row-class">
<td>Height</td>
<td>5.6</td>
</tr>
<tr class="row-class">
<td>Weight</td>
<td>103.4</td>
</tr>
我尝试使用16
和bs4
从相应的行返回lxml
。问题似乎是两个Navigable String
标记之间存在td
,因此
page.find_all("tr", {"class":"row-class"})
使用
生成结果集result[0] = {Tag} <tr class="row-class"> <td>Age</td> <td>16</td> </tr>
result[1] = {Tag} <tr class="row-class"> <td>Height</td> <td>5.6</td> </tr>
result[2] = {Tag} <tr class="row-class"> <td>Weight</td> <td>103.4</td> </tr>
这很棒,但我无法在第二个td
中获得字符串。每个行的内容类似于
[' ', <td>Age</td>, ' ', <td>16</td>, ' ']
td
为tag
,' '
为Navigable String
。这种差异阻止我使用next_element
或next_sibling
便捷方法来访问正确的文本,例如:
如果我使用:
find("td", text=re.compile(r'Age')).get_text()
我得到Age
。但是,如果我尝试通过
find("td", text=re.compile(r'Age')).next_element()
我得到了
&#39; NavigableString&#39;对象不可调用
由于NavigableStrings
中包裹result
,因此previous_element
向后移动会产生同样的问题。
如何从找到的Tag
移动到下一个Tag
,跳过其间的next_element
?有没有办法从' '
中删除这些result
?
我应该指出,我已经尝试过务实,例如:
for r in (sp.find_all("tr", {"class":"row-class"})):
age = r.find("td", text=re.compile(r"\d\d")).get_text()
它有效...直到我在\d\d
之前解析具有匹配Age
的另一个订单的文档。
我也知道,我可以
find("td", text=re.compile(r'Age')).next_sibling.next_sibling
但这对结构来说是难以烘焙的。
所以我需要在搜索中具体,找到具有目标字符串的td
,然后在下一个td
中找到该值。我知道我可以构建一些测试每行的逻辑,但似乎我错过了一些明显且更优雅的东西...
答案 0 :(得分:3)
如果您获得了元素列表,那么您可以使用[index]
从列表中获取元素。
data = """<tr class="row-class">
<td>Age</td>
<td>16</td>
</tr>
<tr class="row-class">
<td>Height</td>
<td>5.6</td>
</tr>
<tr class="row-class">
<td>Weight</td>
<td>103.4</td>
</tr>"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(data)
trs = soup.find_all("tr", {"class":"row-class"})
for tr in trs:
tds = tr.find_all("td") # you get list
print('text:', tds[0].get_text()) # get element [0] from list
print('value:', tds[1].get_text()) # get element [1] from list
结果
text: Age
value: 16
text: Height
value: 5.6
text: Weight
value: 103.4