【问题标题】:Extracting rows from a table从表中提取行
【发布时间】:2015-11-30 16:22:13
【问题描述】:

我正在尝试从下表中提取具有相应单元格的行:

<table border="0" cellspacing="1" cellpading="3" width="100%">
<tr bgcolor="#505050">
    <td><b></b></td>
    <td colspan="2" align="center" class="white"><b>Last Day</b></td>
    <td colspan="2" align="center" class="white"><b>Last Week</b></td>
</tr>
<tr bgcolor="#505050">
    <td class="white"><b>Race</b></td>
    <td align="center" class="white"><b>Killed Players</b></td>
    <td align="center" class="white"><b>Killed by Players</b></td>
    <td align="center" class="white"><b>Killed Players</b></td>
    <td align="center" class="white"><b>Killed by Players</b></td>
</tr>
<tr bgcolor="#F1E0C6">
    <td>A</td>
    <td align="right">0</td>
    <td align="right">3</td>
    <td align="right">0</td>
    <td align="right">13</td>
</tr>
<tr bgcolor="#D4C0A1">
    <td>B</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">7</td>
</tr>
<tr bgcolor="#F1E0C6">
    <td>C</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">1</td>
</tr>
<tr bgcolor="#D4C0A1">
    <td>D</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">7</td>
</tr>
<tr bgcolor="#505050">
    <td class=white><b>Total</b></td>
    <td align="right" class="white"><b>210</b></td>
    <td align="right" class="white"><b>1060458</b></td>
    <td align="right" class="white"><b>1132</b></td>
    <td align="right" class="white"><b>5585115</b></td>
</tr>

我感兴趣的行是带有 A、B、C 等且旁边有数字的行。

我想出的解决办法是:

table = tree.xpath("//table/tr[td[not(contains(@class, 'white'))]]")

for tr in table:
    print( tr.xpath('td/text()'))

但是,输出仍然包括第一行空单元格和 Last Day/Week 单元格,如下所示:

['', 'Last Day', 'Last Week']
['A', '0', '3', '0', '13']
['B', '0', '0', '2', '0']
['C', '0', '3', '0', '5']

可以做些什么来摆脱它?

【问题讨论】:

  • 你能发布你的预期输出吗?
  • 好的,更新了原帖。

标签: python xpath lxml


【解决方案1】:

只需将tr 更改为:

tr[not(contains(@bgcolor, "505050"))]

所以你的代码应该是这样的:

from lxml import html

HTML = """<table border="0" cellspacing="1" cellpading="3" width="100%">
<tr bgcolor="#505050">
    <td><b></b></td>
    <td colspan="2" align="center" class="white"><b>Last Day</b></td>
    <td colspan="2" align="center" class="white"><b>Last Week</b></td>
</tr>
<tr bgcolor="#505050">
    <td class="white"><b>Race</b></td>
    <td align="center" class="white"><b>Killed Players</b></td>
    <td align="center" class="white"><b>Killed by Players</b></td>
    <td align="center" class="white"><b>Killed Players</b></td>
    <td align="center" class="white"><b>Killed by Players</b></td>
</tr>
<tr bgcolor="#F1E0C6">
    <td>A</td>
    <td align="right">0</td>
    <td align="right">3</td>
    <td align="right">0</td>
    <td align="right">13</td>
</tr>
<tr bgcolor="#D4C0A1">
    <td>B</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">7</td>
</tr>
<tr bgcolor="#F1E0C6">
    <td>C</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">1</td>
</tr>
<tr bgcolor="#D4C0A1">
    <td>D</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">0</td>
    <td align="right">7</td>
</tr>
<tr bgcolor="#505050">
    <td class=white><b>Total</b></td>
    <td align="right" class="white"><b>210</b></td>
    <td align="right" class="white"><b>1060458</b></td>
    <td align="right" class="white"><b>1132</b></td>
    <td align="right" class="white"><b>5585115</b></td>
</tr>"""

tree = html.fromstring(HTML)
results = defaultdict

for item in tree.xpath('//table/tr[not(contains(@bgcolor, "505050"))]'):
    print item.xpath('.//td/text()')

还有输出:

['A', '0', '3', '0', '13']
['B', '0', '0', '0', '7']
['C', '0', '0', '0', '1']
['D', '0', '0', '0', '7']

不过,我还是建议使用 dict()。见:

tree = html.fromstring(HTML)
results = dict()

def unpack(data):
    return data[0], data[1:]

for item in tree.xpath('//table/tr[not(contains(@bgcolor, "505050"))]'):
    key, values = unpack(item.xpath('.//td/text()'))
    results[key] = values

print results

输出:

{
    'A': ['0', '3', '0', '13'],
    'C': ['0', '0', '0', '1'],
    'B': ['0', '0', '0', '7'],
    'D': ['0', '0', '0', '7']
}

在 Python 3 中,不需要像上面那样有 unpack() 函数,你只需要改变 key, values = unpack(item.xpath('.//td/text()'))key, *values = item.xpath('.//td/text()')

见:https://www.python.org/dev/peps/pep-3132/


此外,如果需要,您可以使用 sorted() 按字母(键)对结果进行排序:

[
  ('A', ['0', '3', '0', '13']),
  ('B', ['0', '0', '0', '7']),
  ('C', ['0', '0', '0', '1']),
  ('D', ['0', '0', '0', '7'])
]

【讨论】:

  • @我很高兴。如果它帮助您解决问题,请不要忘记接受我的回答:)
猜你喜欢
  • 1970-01-01
  • 2017-02-01
  • 2018-06-16
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
相关资源
最近更新 更多