Scrapy: вернуть каждый элемент в новую строку CSV, используя загрузчик элементов - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь произвести вывод в формате csv выбранных элементов, содержащихся в определенном классе (название, ссылка, цена), который анализирует каждый элемент в своем собственном столбце, и каждый экземпляр в своей собственной строке , используязагрузчики предметов и модуль предметов.

Я могу произвести вывод, используя автономного паука (без использования модуля предметов), однако я пытаюсь изучить правильный способ детализации предметов в модуле предметов, так что я могу со временем масштабировать проекты, используя правильную структуру.(Я детализирую этот код как «Код паука вывода рабочей строки» ниже)

Я также попытался включить решения, определенные или обсужденные в соответствующих публикациях;в частности:

Запись Itemloader By Item в XML или CSV с использованием Scrapy отправлено Sam

Scrapy Return несколько элементов опубликовано Zana Daniel

с помощью цикла for, как он отмечает в нижней части раздела комментариев.Тем не менее, я могу заставить scopy принять цикл for, он просто не приводит к каким-либо изменениям, то есть элементы все еще сгруппированы в отдельные поля, а не выводятся в независимые строки.

Ниже подробнокода, содержащегося в двух попытках проекта - 'Код паука вывода рабочей строки' , который не включает модуль элементов и загрузчик элементов, и 'Код паука вывода рабочей строки' -и соответствующие выходные данные каждого.

Код паука вывода рабочей строки: btobasics.py

import scrapy
import urlparse

class BasicSpider(scrapy.Spider):
    name = 'basic'
    allowed_domains = ['http://http://books.toscrape.com/']
    start_urls = ['http://books.toscrape.com//']

    def parse(self, response):
        titles = response.xpath('//*[@class="product_pod"]/h3//text()').extract()
        links = response.xpath('//*[@class="product_pod"]/h3/a/@href').extract()
        prices = response.xpath('//*[@class="product_pod"]/div[2]/p[1]/text()').extract()

        for item in zip(titles, links, prices):
        # create a dictionary to store the scraped info
            scraped_info = {
                'title': item[0],
                'link': item[1],
                'price': item[2],
            }

            # yield or give the scraped info to scrapy
            yield scraped_info

Команда запуска для создания CSV: $ scrapy crawl basic-o output.csv

Выход рабочей строки БЕЗ СТРУКТУРНЫХ ПОГРУЗЧИКОВ ПУНКТОВ

Нерабочий выходной ряд Код паука: btobasictwo.py

import datetime
import urlparse
import scrapy

from btobasictwo.items import BtobasictwoItem

from scrapy.loader.processors import MapCompose
from scrapy.loader import ItemLoader


class BasicSpider(scrapy.Spider):
    name = 'basic'
    allowed_domains = ['http://http://books.toscrape.com/']
    start_urls = ['http://books.toscrape.com//']

    def parse(self, response):
        # Create the loader using the response
        links = response.xpath('//*[@class="product_pod"]')
        for link in links:
            l = ItemLoader(item=BtobasictwoItem(), response=response)

            # Load fields using XPath expressions
            l.add_xpath('title', '//*[@class="product_pod"]/h3//text()',
                        MapCompose(unicode.strip))
            l.add_xpath('link', '//*[@class="product_pod"]/h3/a/@href',
                        MapCompose(lambda i: urlparse.urljoin(response.url, i)))
            l.add_xpath('price', '//*[@class="product_pod"]/div[2]/p[1]/text()',
                        MapCompose(unicode.strip))
            # Log fields
            l.add_value('url', response.url)
            l.add_value('date', datetime.datetime.now())

            return l.load_item()

Нерабочие элементы вывода строки Код: btobasictwo.items.py

from scrapy.item import Item, Field


class BtobasictwoItem(Item):
    # Primary fields
    title = Field()
    link = Field()
    price = Field()
    # Log fields
    url = Field()
    date = Field()

Команда запуска для создания CSV: $ scrapy crawl basic -ooutput.csv

Неработающий код строки Output со структурированными загрузчиками элементов

Как вы можете видеть, при попытке включить модуль items, загрузчики элементов и цикл for для структурирования данных он не разделяет экземпляры по строкам, а скорее помещает всеэкземпляры определенного элемента (заголовок, ссылка, цена) в 3 полях.

Я был бы очень признателен за любую помощь в этом, и приношу извинения за длинный пост.Я просто хотел документировать как можно больше, чтобы каждый, кто хотел помочь, мог сам выполнить код и / или полностью оценить проблему из моей документации.(пожалуйста, оставьте комментарий с указанием длины сообщения, если вы считаете, что не следует так долго).

Большое спасибо

1 Ответ

0 голосов
/ 14 сентября 2018

Вы должны указать своему ItemLoader, чтобы использовать другое selector:

def parse(self, response):
    # Create the loader using the response
    links = response.xpath('//*[@class="product_pod"]')
    for link in links:
        l = ItemLoader(item=BtobasictwoItem(), selector=link)

        # Load fields using XPath expressions
        l.add_xpath('title', './/h3//text()',
                    MapCompose(unicode.strip))
        l.add_xpath('link', './/h3/a/@href',
                    MapCompose(lambda i: urlparse.urljoin(response.url, i)))
        l.add_xpath('price', './/div[2]/p[1]/text()',
                    MapCompose(unicode.strip))
        # Log fields
        l.add_value('url', response.url)
        l.add_value('date', datetime.datetime.now())

        yield l.load_item()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...