从表中无标题地抓取提取行

时间:2018-09-11 12:40:16

标签: python scrapy

因此,我正在尝试从网站中提取表格。这是一个两列的表,如下所示:

Name      Foo
Number    Foo123
Address   10
          First Drive
          London
          AB34 5FG
Region    United Kingdom

该表没有标题,并且“地址”行的第一列中包含空白单元格,用于第二,城市,邮政编码等。

我已经设法得到桌子了,很好。

table = response.xpath('//table[@id="MemberDetails"]/tr/td//text()')

这是输出:

[<Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'Name:\xa0'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\r\nFoo\xa0\r\n'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'Number:\xa0'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\r\nFoo123\xa0\r\n'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'Address:\xa0'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\r\n(10)\xa0\r\n'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\xa0'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\r\nFirst Drive\xa0\r\n'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\xa0'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\r\nLondon\xa0\r\n'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\xa0'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\r\nAB34 5FG\xa0\r\n'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\xa0'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\r\nUnited Kingdom\xa0\r\n'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'Region:\xa0'>,
 <Selector xpath='//table[@id="MemberDetails"]/tr/td//text()' data=u'\r\nUnited Kingdom\xa0\r\n'>]

但是,我对如何将表解析为适当的结构感到困惑。

第一个问题:不确定如何处理地址字段。 第二个问题:这是两列的表。保存此内容时,我要进行转置,以使“名称,数字,地址,区域”为列标题。

有1000多个这样的页面包含相似的数据。

感谢有人能指出我正确的方向。

3 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

            DataTable dt = new DataTable();
            OleDbDataAdapter adapter = new OleDbDataAdapter();
            adapter.Fill(dt, Dts.Variables["User::YourObjectVariable"].Value);

            foreach (DataRow r in dt.Rows)
            {
                r["Column"] = " "; //Do work here

            }

            Dts.Variables["User::YourObjectVariable"].Value = dt;

它不能在所有情况下都起作用(例如,在链接data = {} rows = response.css('table#MemberDetails tr') for row in rows: label = row.css('td:nth-child(1) strong::text').extract_first().strip() value = row.css('td+td::text').extract_first().strip() if label: label = label.replace(':', '') data[label] = value else: data['Address'] = data['Address'] + ', ' + value print(data) 中的标签位于Herd Completeness of Performance Rating:标签中,并且值是图像),但是您已经有了解决方案的开始:) / p>

其他解决方案:

<a>

答案 1 :(得分:1)

让我们处理您提供给我们的样本。 (使用this link

让我们看看表格行是如何格式化的。

<tr>
<td bgcolor="#7EADAD">
<strong>Membership Name:&nbsp;</strong>
</td>
<td>
MESSRS R J &amp; L A ACTON&nbsp;
</td>
</tr>

这对我们非常有用,我们具有不同的标头和值属性:标头位于strong内的td标记内,其中bgcolor的值直接位于其{{1} } s。

让我们检查一下地址信息的空行外观:

td

很棒,结构相同。

这意味着我们可以遍历所有<tr> <td bgcolor="#7EADAD"> <strong>&nbsp;</strong> </td> <td> NORTHUMBERLAND&nbsp; </td> </tr> 并根据需要根据属性获取它们的数据。 这是一个不处理链接的最小示例:

tr

下一步是收集数据(创建字典?单独的列表?直接写到文件?由您选择。)

用于处理地址:如果报头为空(假设仅地址报头为空),则可以在for tr in response.xpath('//table[@id="MemberDetails"]/tr'): header = tr.xpath('td/strong/text()').extract()[0].strip() value = tr.xpath('td')[1].xpath('text()').extract()[0].strip() print(u'{} -- {}'.format(header, value)) 的循环中为该地址变量与该值连接。这样的事情(再次是<最小的例子):

tr

您还必须弄清楚如何处理存储在for tr in response.xpath('//table[@id="MemberDetails"]/tr'): address = '' header = tr.xpath('td/strong/text()').extract()[0].strip() value = tr.xpath('td')[1].xpath('text()').extract()[0].strip() if not header: # empty strings evaluate to False address += '' + value 标记中的标头/值。

答案 2 :(得分:1)

您可以为表中的所有行生成一个字典:

def parse(self, response):

    table_data = {}
    current_key = None

    for tr in response.xpath('//table[@id="MemberDetails"]//tr'):

        key = tr.xpath('string(./td[1])').extract_first()
        value = tr.xpath('string(./td[2])').extract_first()

        if key:
            key = key.strip()
            key = key.replace(":", "")
        if value:
            value = value.strip()

        if key:
            current_key = key

        if current_key in table_data:
            table_data[current_key] += '\n' + value
        else:
            table_data[current_key] = value

    print(table_data["Address"])