Элемент Scrapy сохраняет только последний элемент цикла - PullRequest
0 голосов
/ 07 июня 2018

Я использую библиотеку Scrapy для сканирования данных с веб-сайта.

Я получаю результат сканирования сайта и хочу сохранить его в базе данных.Я использую предмет Scrapy и конвейер для этого.

Я получил список, поэтому мне нужно использовать цикл for для сохранения item.Но проблема в том, что сохраняется последний элемент в списке.

Мой код выглядит следующим образом:

def parse(self, response):
    vehicles = []
    total_results = response.css('.cl-filters-summary-counter::text').extract_first().replace('.', '')

    reference_urls = []
    for url in response.css('.cldt-summary-titles'):
        reference_url = url.css("a::attr(href)").extract_first().strip(' \t\n\r')
        reference_urls.append(reference_url)

    ids = []
    for item in response.css('.cldt-summary-full-item'):
        car_id = item.css("::attr(id)").extract_first().strip(' \t\n\rli-')
        ids.append(car_id)

    for item in response.css('.cldt-price'):
        dirty_price = item.css("::text").extract_first().strip(' \t\n\r')
        comma = dirty_price.index(",-")
        price = dirty_price[2:comma].replace('.', '')
        prices.append(price)

    for item in zip(ids, reference_urls, prices):
        car = CarItem()
        car['reference'] = item[0]
        car['reference_url'] = item[1]
        car['data'] = ""
        car['price'] = item[2]
        return car

Результат, полученный при сканировании, хороший.Если я в цикле for сделаю что-то следующим образом:

vehicles = []
for item in zip(ids, reference_urls, prices):
     scraped_info = {
         "reference": item[0],
         "reference_url": item[1],
         "price": item[2]
     }
     vehicles.append(scraped_info)

И если я напечатаю vehicles, я получу правильный результат:

[
    {
        "price": "4250",
        "reference": "6784086e-1afb-216d-e053-e250040a033f",
        "reference_url": "some-link-1"
    },
    {
        "price": "4250",
        "reference": "c05595ac-e49e-4b71-a436-868c192ef82c",
        "reference_url": "some-link-2"
    },
    {
        "price": "4900",
        "reference": "444553f2-e8fd-41c9-9244-182668544e2a",
        "reference_url": "some-link-3"
    }
]

ОБНОВЛЕНИЕ

CarItem - это всего лишь скрап-элемент в items.py

class CarItem(scrapy.Item):
    # define the fields for your item here like:
    reference = scrapy.Field()
    reference_url = scrapy.Field()
    data = scrapy.Field()
    price = scrapy.Field()

Есть идеи, что я делаю не так?

1 Ответ

0 голосов
/ 08 июня 2018

Согласно Scrapy Document , метод parse

, как и любой другой обратный вызов запроса, должен возвращать повторяемый запроса и/ или диктовки или объекты Item.

Кроме того, в соответствии с примером кода, приведенным под этой ссылкой,

import scrapy
from myproject.items import MyItem

class MySpider(scrapy.Spider):
    name = 'example.com'
    allowed_domains = ['example.com']

    def start_requests(self):
        yield scrapy.Request('http://www.example.com/1.html', self.parse)
        yield scrapy.Request('http://www.example.com/2.html', self.parse)
        yield scrapy.Request('http://www.example.com/3.html', self.parse)

    def parse(self, response):
        for h3 in response.xpath('//h3').extract():
            yield MyItem(title=h3)

        for url in response.xpath('//a/@href').extract():
            yield scrapy.Request(url, callback=self.parse)

Мы можем видеть, что мы должны использовать yield для получения правильных результатов изparse function.

tl; dr : замените return в вашей последней строке на yield.

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