Как отсортировать информацию об элементе скрапа в индивидуальном порядке? - PullRequest
2 голосов
/ 25 апреля 2019

Порядок по умолчанию в scrapy - алфавит, я прочитал некоторые посты, чтобы использовать OrderedDict для вывода элемента в произвольном порядке.
Я пишу паук, следите за веб-страницей.
Как получить порядок полей в 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号浙能大厦']}

Спасибо за совет Галласио, чтобы добавить следующее в 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 ]

1 голос
/ 30 апреля 2019

Проблема в __repr__ функции 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

И теперь вы можете получить этот вывод:

2019-04-30 18:56:20 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.money.163.com/f10/gszl_600023.html>
{"name": ["\u6d59\u80fd\u7535\u529b"], "phone": ["0571-87210223"], "address": ["\u6d59\u6c5f\u7701\u676d\u5dde\u5e02\u5929\u76ee\u5c71\u8def152\u53f7\u6d59\u80fd\u5927\u53a6"]}
0 голосов
/ 02 мая 2019

Весь файл items.py, который может выводить настраиваемую информацию dubug в cjk apperance, представлен ниже.

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()
0 голосов
/ 28 апреля 2019

В вашем пауке замените item.items() на self.log(item.items()), в журнале сообщений должен быть список кортежей, чтобы вы присвоили их в своем пауке.

Другой способ - объединить ответ, упомянутый в вашем сообщении, с этот ответ

0 голосов
/ 28 апреля 2019

вы можете определить пользовательское строковое представление вашего элемента

class InfoItem:
    def __repr__(self):
      return 'name: {}, phone: {}, address: {}'.format(self['name'], self.['phone'], self.['address'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...