【问题标题】:using scrapy to parse an arbitrary number of rows (key:value pairs) in an html table使用 scrapy 解析 html 表中任意数量的行(键:值对)
【发布时间】:2012-03-18 08:20:06
【问题描述】:

最近开始使用 scrapy 库。我试图从一个网站上抓取他们销售的每种产品的表格略有不同。最终,我将使用这些数据来填充对象属性。现在,我只需要将其提取为 JSON 格式。

这是一个示例表:

<table id="table_1">
<tr id="row_1">
    <td>cell_1</td>
    <td>cell_2</td>
    <td>cell_3</td>
</tr>
<tr id="row_2">
    <td>cell_4</td>
    <td>cell_5</td>
    <td>cell_6</td>
</tr>
<tr id="row_n">
    <td>cell_x</td>
    <td>cell_y</td>
    <td>cell_z</td>
</tr>
</table>

每一列代表一个不同的项目,即小号中号或大号 T 恤。 上表中将有 3 个项目,因此项目如下所示:

Item 1 {
    row_1:cell_1
    row_2:cell_4
    row_n:cell_x
}
Item 2 {
    row_1:cell_2
    row_2:cell_5
    row_n:cell_y
}
Item 3 {
    row_1:cell_3
    row_2:cell_6
    row_n:cell_z
}

它们是结构良好的表格,没有“缺失”或“额外”单元格,尽管行数和列数是任意的。

我遇到的困难在于使用 scrapy Item 对象,因为这需要我的 Item 类在抓取之前定义字段的数量,而不是基于每个表。我有数百个表要执行此过程。

感谢您阅读本文,感谢您提供任何帮助。 :)

解决方案:@warawuk 感谢您的帮助。我使用了你的建议,最终得到了一个三重嵌套列表。也许并不理想,但在我继续使用它们时提取这些值已经足够微不足道了:

{"tRows": 
    [[["row1"], ["cell1", "cell2"]]
    [["row2"], ["cell3", "cell4"]]
    [["row3"], ["cell5", "cell6"]]
    [["row4"], ["cell7", "cell8"]]] x100s of tables
}

为了处理任意数量的行,我使用正则表达式从每行中提取 id 并对其进行计数。一个使用 range(len(rowNames)) 的简单循环,加上一些字符串连接完成了这项工作。

【问题讨论】:

    标签: python xpath scrapy web-crawler scrape


    【解决方案1】:

    你的问题太多了,imo。

    首先,看起来你的问题根本不是关于scrapy的。这是关于组织您的数据和 xpath。

    我认为您必须将任务拆分为子任务。第一个子任务是将数据实际提取到 python 数据结构中,然后尝试对其进行处理。根据您的信息,我认为数据会是这样的:

    {
        'table_1': {
            'row_1': ['cell_1', 'cell_2'],
            'row_2': ['cell_1', 'cell_2'],
            ...
        },
        'table_2': {
            'row_1': ['cell_1', 'cell_2', 'cell_3'],
            'row_2': ['cell_1', 'cell_2', 'cell_3'],
            ...
        },
    }
    

    这对吗?


    更新:

    我遇到的困难是使用scrapy Item 对象,因为这个 需要我的 Item 类在抓取之前定义字段的数量, 而不是按表计算。我有数百张桌子想要 执行此过程。

    AFAIK,Item Fields can store any Python object。 Scrapy Item 类只是你存储Fields 的地方,但是scrapy 并没有特殊对待这些字段。只有您将这些字段纳入管道并解释其中的数据。

    因此,请选择适合您的任何商店形式。例如:

    class Shirt(Item):
        available_sizes = Field() # [(size1, amount1), (size2, amount2), ...] or {size1: amount1, size2: amount2, ...} if `size` is a hashable object
    

    【讨论】:

    • 是的,没错。将数据输入这种形式是主要障碍。让我们将子任务 1 定义为在每个表中抓取任意数量的行并将其转换为这样的格式。根据我对scrapy Items的了解,似乎我需要提前定义字段的数量及其名称,在这种情况下,我想在scrape期间确定这些。
    • 你想在 Item 实例中包含什么?
    • 对于表中的每一行,每个项目中的键:值对应类似于 'row_1':'cell_1'、'row_2':'cell_1' 等。每行可以代表一个字段。
    • 那么 cell_2、cell_3 等呢?
    • 感谢您的回复。我发现我无法清楚地传达所有内容。我编辑了我的原始帖子以澄清和缩小问题的范围。请再看一看。
    猜你喜欢
    • 2021-10-24
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 2019-04-28
    相关资源
    最近更新 更多