如何让Beautiful Soup在解析时不跳过行?

3 投票
1 回答
682 浏览
提问于 2025-04-15 20:06

在使用BeautifulSoup这个工具解析HTML中的表格时,发现每隔一行就会出现

<tr class="row_k">

而不是没有类的tr标签

示例HTML代码

<tr class="row_k"> 
<td><img src="some picture url" alt="Item A"></td> 
<td><a href="some url"> Item A</a></td> 
<td>14.8k</td> 
<td><span class="drop">-555</span></td> 
<td> 
<img src="some picture url" alt="stuff" title="stuff"> 
</td> 
<td> 
<img src="some picture url" alt="Max llll"> 
</td> 
</tr> 
<tr> 
<td><img src="some picture url" alt="Item B"></td> 
<td><a href="some url"> Item B</a></td> 
<td>64.9k</td> 
<td><span class="rise">+165</span></td> 
<td> 
<img src="some picture url" alt="stuff" title="stuff"> 
</td> 
<td> 
<img src="some picture url" alt="max llll"> 
</td> 
</tr> 
<tr class="row_k"> 
<td><img src="some picture url" alt="Item C"></td> 
<td><a href="some url"> Item C</a></td> 
<td>4,000</td> 
<td><span class="rise">+666</span></td> 
<td> 
<img src="some picture url" title="stuff"> 
</td> 
<td> 
<img src="some picture url" alt="Maximum lllle"> 

我想提取的文本是 14.8k、64.9k 和 4,000

this1 = urllib2.urlopen('my url').read()
this_1 = BeautifulSoup(this1)
this_1a = StringIO.StringIO()
for row in this_1.findAll("tr", { "class" : "row_k" }):
  for col in row.findAll(re.compile('td')):
    this_1a.write(col.string if col.string else '')
Item_this1 = this_1a.getvalue()

我感觉这段代码写得不太好,有没有人能推荐一个更灵活的工具,比如XML解析器?

我仍然欢迎任何使用BeautifulSoup的答案。

1 个回答

2

我还在学习很多东西,但我建议你试试lxml这个库。我会尽量给你一些建议,我觉得这样做大部分情况下是有效的,但可能有些细节我不太确定。

假设这个变量是一个字符串

from lxml.html import fromstring
this1_tree=fromstring(this1)
all_cells=[(item[0], item[1]) for item in enumerate(this1_tree.cssselect('td'))] # I am hoping this gives you the cells with their relative position in the document)

我唯一不太确定的是,你是检查每个单元格的键、值还是文本内容,以找出是否包含你想要的字符串。这就是我想要你提供一些HTML示例的原因。不过其中一个方法应该是可行的。

the_cell_before_numbers=[]
for cell in all_cells:
    if 'Item' in cell[1].text_content():
        the_cell_before_numbers.append(cell[0])

现在你已经找到了那个单元格,你可以通过获取下一个单元格的文本内容来得到你需要的值。

todays_price=all_cells[the_cell_before_number+1][1].text_content()

我相信还有更好的方法,但我觉得这样做是可以的。

我用你的HTML做了测试,得到了你想要的结果。

撰写回答