Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在scrapy/python中创建用于解析表数据的循环_Python_Xpath_Web Scraping_Web Crawler_Scrapy - Fatal编程技术网

在scrapy/python中创建用于解析表数据的循环

在scrapy/python中创建用于解析表数据的循环,python,xpath,web-scraping,web-crawler,scrapy,Python,Xpath,Web Scraping,Web Crawler,Scrapy,让python脚本使用scrapy,它从网站上刮取数据,将其分配到3个字段,然后生成一个.csv。工作正常,但有一个主要问题。所有字段都包含所有数据,而不是为每个表行分隔数据。我确信这是由于我的循环不起作用,当它找到xpath时,它只是获取每一行的所有数据,然后继续获取其他两个字段的数据,而不是创建单独的行 def parse(self, response): hxs = HtmlXPathSelector(response) divs = hxs.select('//tr[@c

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

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)

我想这就是你想要的:

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
s上循环,然后使用相对XPath表达式(
/td…
),在每次迭代中使用
产生
指令

您还可以将每个项附加到列表中,并在循环的外部返回该列表(如下所示(与上面的代码等效):


您不需要
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

如果你能告诉我如何附加到循环之外的列表中,这将有助于我收集更多的数据。我试图在“pipelines.py”中写入一些验证,但它似乎忽略了它并输出了所有数据,甚至是不符合条件的数据。我用循环外返回的项目列表更新了我的答案。您可能应该在一些pastebin服务中共享您的爬行器和管道代码,以便我们检查。另外,在
div
s的循环中,确保使用的是相对的XPath表达式,例如
/td[2]/p/span[2]/text()
,而不是像
/td[2]/p/span[2]/text()这样的绝对表达式
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