使用使用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)
我认为这是你要寻找的:
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
在trs 上循环,然后使用相对的XPath表达式(./td...),并且在每次迭代中都使用yield指令。
trs
./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