4

使用 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)
4

2 回答 2

7

我认为这就是你要找的:

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

您在 s 上循环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
于 2013-10-31T13:43:28.793 回答
4

你不需要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
于 2016-01-23T03:09:15.627 回答