如何在解析时停止漂亮的汤?

时间:2010-03-06 22:19:06

标签: python xml tags urllib2 beautifulsoup

使用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 个答案:

答案 0 :(得分:2)

我还在学习很多,但我建议你试试lxml。我将对此进行一次尝试,我认为它主要会让你到那里,但可能会有一些我不确定的细节。

假设this1是一个字符串

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)

我唯一不确定的是你是否测试每个单元格的键或值或text_content,以确定它是否具有您在锚点引用或文本中寻找的字符串。这就是我想要你的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进行测试,我得到了你想要的东西。