如何按照自定义顺序对易碎物品信息进行排序?

时间:2019-04-25 14:00:46

标签: python scrapy

scrapy的默认顺序是字母,我已经阅读过一些文章,可以使用OrderedDict以自定义顺序输出项目。
我按照网页写了一个蜘蛛。
How to get order of fields in Scrapy item

我的items.py。

import scrapy
from collections import OrderedDict


class OrderedItem(scrapy.Item):
    def __init__(self, *args, **kwargs):
        self._values = OrderedDict()
        if args or kwargs:  
            for k, v in six.iteritems(dict(*args, **kwargs)):
                self[k] = v

class StockinfoItem(OrderedItem):
    name = scrapy.Field()
    phone = scrapy.Field()
    address = scrapy.Field()

简单的蜘蛛文件。

import scrapy
from info.items import InfoItem

class InfoSpider(scrapy.Spider):
    name = 'Info'
    allowed_domains = ['quotes.money.163.com']
    start_urls = [ "http://quotes.money.163.com/f10/gszl_600023.html"]
    def parse(self, response):
        item = InfoItem()
        item["name"] = response.xpath('/html/body/div[2]/div[4]/table/tr[2]/td[2]/text()').extract()
        item["phone"] = response.xpath('/html/body/div[2]/div[4]/table/tr[7]/td[4]/text()').extract()
        item["address"] = response.xpath('/html/body/div[2]/div[4]/table/tr[2]/td[4]/text()').extract()
        item.items()
        yield  item

何时运行蜘蛛的抓斗信息。

2019-04-25 13:45:01 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.money.163.com/f10/gszl_600023.html>
{'address': ['浙江省杭州市天目山路152号浙能大厦'],'name': ['浙能电力'],'phone': ['0571-87210223']}

为什么我不能得到以下想要的订单?

{'name': ['浙能电力'],'phone': ['0571-87210223'],'address': ['浙江省杭州市天目山路152号浙能大厦']}

感谢Gallaecio的建议,在settings.py中添加以下内容。

FEED_EXPORT_FIELDS=['name','phone','address']

执行蜘蛛程序并输出到csv文件。

scrapy crawl  info -o  info.csv

现场订单是我自定义的订单。

cat info.csv
name,phone,address
浙能电力,0571-87210223,浙江省杭州市天目山路152号浙能大

查看scrapy的调试信息:

2019-04-26 00:16:38 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.money.163.com/f10/gszl_600023.html>
{'address': ['浙江省杭州市天目山路152号浙能大厦'],
 'name': ['浙能电力'],
 'phone': ['0571-87210223']}

如何按自定义顺序制作调试信息?如何获得以下调试输出?

2019-04-26 00:16:38 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.money.163.com/f10/gszl_600023.html>
{'name': ['浙能电力'],
 'phone': ['0571-87210223'],
 'address': ['浙江省杭州市天目山路152号浙能大厦'],}

4 个答案:

答案 0 :(得分:1)

问题在__repr__的{​​{1}}函数中。原来它的代码是:

Item

因此,即使您将项目转换为def __repr__(self): return pformat(dict(self)) 并期望字段以相同的顺序保存,此功能也会对其应用OrderedDict并中断顺序。

因此,我建议您以自己喜欢的方式重载它,例如:

dict()

现在您可以得到以下输出:

import json

class OrderedItem(scrapy.Item):
    def __init__(self, *args, **kwargs):
        self._values = OrderedDict()
        if args or kwargs:
            for k, v in six.iteritems(dict(*args, **kwargs)):
                self[k] = v

    def __repr__(self):
        return json.dumps(OrderedDict(self), ensure_ascii = False)  # it should return some string

答案 1 :(得分:0)

您可以定义商品的自定义字符串表示形式

class InfoItem:
    def __repr__(self):
      return 'name: {}, phone: {}, address: {}'.format(self['name'], self.['phone'], self.['address'])

答案 2 :(得分:0)

在您的蜘蛛程序中,将item.items()替换为self.log(item.items()),日志味精应该是元组列表,以便在蜘蛛程序中分配它们。

另一种方法是将您在帖子中提到的答案与this answer

结合起来

答案 3 :(得分:0)

可以在cjk外观中输出自定义dubug信息的整个items.py如下。

import scrapy
import json    
from collections import OrderedDict

class OrderedItem(scrapy.Item):
    def __init__(self, *args, **kwargs):
        self._values = OrderedDict()
        if args or kwargs:
            for k, v in six.iteritems(dict(*args, **kwargs)):
                self[k] = v

    def __repr__(self):
        return json.dumps(OrderedDict(self),ensure_ascii = False)  
        #ensure_ascii = False ,it make characters show in cjk appearance.

class StockinfoItem(OrderedItem):
    name = scrapy.Field()
    phone = scrapy.Field()
    address = scrapy.Field()