创建循环以解析scrapy / python中的表数据

时间:2013-10-31 13:34:59

标签: python xpath web-scraping web-crawler scrapy

使用scrapy的python脚本,它从网站上抓取数据,将其分配到3个字段,然后生成.csv。工作正常,但有一个主要问题。所有字段都包含所有数据,而不是为每个表行分离。我确定这是由于我的循环不起作用,当它找到xpath时它只是抓取每一行的所有数据,然后继续获取其他2个字段的数据,而不是创建单独的行

def parse(self, response):
    hxs = HtmlXPathSelector(response)
    divs = hxs.select('//tr[@class="someclass"]')
    for div in divs:
        item = TestBotItem()
        item['var1'] = div.select('//table/tbody/tr[*]/td[2]/p/span[2]/text()').extract()
        item['var2'] = div.select('//table/tbody/tr[*]/td[3]/p/span[2]/text()').extract() 
        item['var3'] = div.select('//table/tbody/tr[*]/td[4]/p/text()').extract()
        return item

带有*的tr增加了我需要抓取的网站上的每个条目,其他两个路径插入下面。我如何编辑这个,所以它只抓取说// table / tbody / tr [3]的第一组数据,将它存储到所有三个字段,然后转到// table / tbody / tr [4]等? ?

更新

正常工作,但我正在尝试向pipelines.py文件添加一些验证,以删除var1大于100%的所有记录。我确定下面的代码是错误的,而且“yield”而不是“return”会停止使用的管道吗?

from scrapy.exceptions import DropItem 

class TestbotPipeline(object):
def process_item(self, item, spider):
    if item('var1') > 100%:
        return item
    else: 
        raise Dropitem(item)

2 个答案:

答案 0 :(得分:6)

我认为这就是你要找的东西:

def parse(self, response):
    hxs = HtmlXPathSelector(response)
    divs = hxs.select('//tr[@class="someclass"]')
    for div in divs:
        item = TestBotItem()
        item['var1'] = div.select('./td[2]/p/span[2]/text()').extract()
        item['var2'] = div.select('./td[3]/p/span[2]/text()').extract() 
        item['var3'] = div.select('./td[4]/p/text()').extract()

        yield item

循环tr然后使用相对XPath表达式(./td...),并在每次迭代中使用yield指令。

您还可以将每个项目附加到列表中并返回该列表之外的循环中),如下所示(它等同于上面的代码):

def parse(self, response):
    hxs = HtmlXPathSelector(response)
    divs = hxs.select('//tr[@class="someclass"]')
    items = []

    for div in divs:

        item = TestBotItem()
        item['var1'] = div.select('./td[2]/p/span[2]/text()').extract()
        item['var2'] = div.select('./td[3]/p/span[2]/text()').extract() 
        item['var3'] = div.select('./td[4]/p/text()').extract()

        items.append(item)

    return items

答案 1 :(得分:2)

您不需要HtmlXPathSelector。 Scrapy已经内置了XPATH选择器。试试这个:

def parse(self, response):
    divs = response.xpath('//tr[@class="someclass"]')
    for div in divs:
        item = TestBotItem()
        item['var1'] = div.xpath('table/tbody/tr[*]/td[2]/p/span[2]/text()').extract()[0]
        item['var2'] = div.xpath('table/tbody/tr[*]/td[3]/p/span[2]/text()').extract()[0] 
        item['var3'] = div.xpath('table/tbody/tr[*]/td[4]/p/text()').extract()[0]
        return item