Scrapy, как определить пользовательские ItemExporters [duplicate]

Попробуйте это

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysqli_query('SELECT * FROM Users WHERE UserName LIKE $username');

if($result){
while($row = mysqli_fetch_array($result))
{
    echo $row['FirstName'];
}
}
6
задан bnussey 22 October 2015 в 21:15
поделиться

1 ответ

Верно, что в документации Scrapy четко не указано, где разместить экспонента товаров. Чтобы использовать элемент Экспортер, выполните следующие действия.

  1. Выберите класс Экспортер элемента и импортируйте его в pipeline.py в каталоге проекта. Это может быть предопределенный Item Exporter (например, XmlItemExporter) или определенный пользователем (например, FanItemExporter, определенный в вопросе)
  2. Создайте класс Pipeline Item в pipeline.py. Создайте экземпляр импортированного Item Exporter в этом классе. Подробности будут объяснены в более поздней части ответа.
  3. Теперь зарегистрируйте этот класс конвейера в файле settings.py.

Ниже приводится подробное объяснение каждого шага , Решение вопроса включено в каждый шаг.

Шаг 1

  • При использовании заданного класса Item Exporter импортируйте его из модуля scrapy.exporters. Пример: from scrapy.exporters import XmlItemExporter
  • Если вам нужен пользовательский экспортер, определите пользовательский класс в файле. Я предлагаю поместить класс в файл exporters.py. Поместите этот файл в папку проекта (где settings.py, items.py находятся). При создании нового подкласса всегда рекомендуется импортировать BaseItemExporter. Было бы целесообразно, если мы намерены полностью изменить функциональность. Однако в этом вопросе большая часть функциональности близка к JsonLinesItemExporter.

Следовательно, я прикрепляю две версии одного и того же ItemExporter. Одна версия расширяет класс BaseItemExporter, а другая расширяет JsonLinesItemExporter класс

Версия 1 : Расширение BaseItemExporter

Поскольку BaseItemExporter является родительским класс start_exporting(), finish_exporting(), export_item() должен быть переопределен в соответствии с нашими потребностями.

from scrapy.exporters import BaseItemExporter
from scrapy.utils.serialize import ScrapyJSONEncoder
from scrapy.utils.python import to_bytes

class FanItemExporter(BaseItemExporter):

    def __init__(self, file, **kwargs):
        self._configure(kwargs, dont_fail=True)
        self.file = file
        self.encoder = ScrapyJSONEncoder(**kwargs)
        self.first_item = True

    def start_exporting(self):
        self.file.write(b'{\'product\': [')

    def finish_exporting(self):
        self.file.write(b'\n]}')

    def export_item(self, item):
        if self.first_item:
            self.first_item = False
        else:
            self.file.write(b',\n')
        itemdict = dict(self._get_serialized_fields(item))
        self.file.write(to_bytes(self.encoder.encode(itemdict)))

Версия 2 : Расширение JsonLinesItemExporter

JsonLinesItemExporter обеспечивает точно такую ​​же реализацию метода export_item(). Поэтому переопределяются только методы start_exporting() и finish_exporting().

Реализация JsonLinesItemExporter показана в папке python_dir\pkgs\scrapy-1.1.0-py35_0\Lib\site-packages\scrapy\exporters.py

from scrapy.exporters import JsonItemExporter

class FanItemExporter(JsonItemExporter):

    def __init__(self, file, **kwargs):
        # To initialize the object we use JsonItemExporter's constructor
        super().__init__(file)

    def start_exporting(self):
        self.file.write(b'{\'product\': [')

    def finish_exporting(self):
        self.file.write(b'\n]}')

Примечание: при записи данных в файл, важно отметить, что стандартные классы Item Exporter ожидают двоичные файлы. Следовательно, мы должны открыть файл с двоичным режимом (b). По той же причине метод write() в обеих версиях записывает bytes в файл.

Шаг 2

Создание класса Pipeline Item.

from project_name.exporters import FanItemExporter

class FanExportPipeline(object):
    def __init__(self, file_name):
        # Storing output filename
        self.file_name = file_name
        # Creating a file handle and setting it to None
        self.file_handle = None

    @classmethod
    def from_crawler(cls, crawler):
        # getting the value of FILE_NAME field from settings.py
        output_file_name = crawler.settings.get('FILE_NAME')

        # cls() calls FanExportPipeline's constructor
        # Returning a FanExportPipeline object
        return cls(output_file_name)

    def open_spider(self, spider):
        print('Custom export opened')

        # Opening file in binary-write mode
        file = open(self.file_name, 'wb')
        self.file_handle = file

        # Creating a FanItemExporter object and initiating export
        self.exporter = FanItemExporter(file)
        self.exporter.start_exporting()

    def close_spider(self, spider):
        print('Custom Exporter closed')

        # Ending the export to file from FanItemExport object
        self.exporter.finish_exporting()

        # Closing the opened output file
        self.file_handle.close()

    def process_item(self, item, spider):
        # passing the item to FanItemExporter object for expoting to file
        self.exporter.export_item(item)
        return item

Шаг 3

Теперь, когда мы определили Конвейер экспорта товаров, нам необходимо зарегистрировать конвейер в файле settings.py. Мы также используем поле FILE_NAME из файла settings.py. Это поле содержит имя файла выходного файла.

Добавьте следующие строки в файл settings.py.

FILE_NAME = 'path/outputfile.ext'
ITEM_PIPELINES = {
    'project_name.pipelines.FanExportPipeline' : 600,
}

Если ITEM_PIPELINES уже раскоментирован, добавьте следующую строку в словарь ITEM_PIPELINES.

'project_name.pipelines.FanExportPipeline' : 600,

Таким образом, мы можем создавать настраиваемые конвейеры экспорта товаров и использовать их в нашем проекте.

11
ответ дан pbskumar 26 August 2018 в 04:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: