Я не получаю все данные описания продукта с помощью Scrapy - PullRequest
1 голос
/ 23 апреля 2020

Я занимаюсь веб-очисткой в ​​учебных целях, я даже на базовом c уровне очистки. Следующая проблема заключается в том, что когда я запускаю очистку, получаемые данные становятся маленькими, а другие данные равны нулю.

Это код:

items.py

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class MercadolibreItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    #departamento = scrapy.Field()
    #precio = scrapy.Field()
    descripcion = scrapy.Field()
    pass

mercadolibreperu.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from mercadolibre.items import MercadolibreItem

class MercadolibreperuSpider(CrawlSpider):
    name = 'mercadolibreperu'
    allowed_domains = ['mercadolibre.com.pe']
    start_urls = ['https://listado.mercadolibre.com.pe/lima/mascarilla-n95_ITEM*CONDITION_2230284']

    rules = (
        #Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
        Rule(
            LinkExtractor(
                restrict_xpaths=(
                    '//section[@id="results-section"]',        
                ),
            ),
            callback='parse_item',
            follow=True
        ),
    )

    def parse_item(self, response):
        #item = {}
        #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
        #item['name'] = response.xpath('//div[@id="name"]').get()
        #item['description'] = response.xpath('//div[@id="description"]').get()
        item = MercadolibreItem()
        item['descripcion'] = response.xpath('//h2[@class="item__title list-view-item-title"]/a/span/text()').get()
        return item

Полученные результаты: mercadolibre. json

[
{"descripcion": null},
{"descripcion": " Mascarillas N95: 3m - 8210 Oferta!!! "},
{"descripcion": " Mascarillas N95 "},
{"descripcion": " Agotado Mascarillas N95 Sin Filtro "},
{"descripcion": " Mascarilla Steelpro M920v - N95 ( Caja De 10 Uni) Oferta "},
{"descripcion": " Mascarillas 3m 8511 N95 "},
{"descripcion": " Mascarillas N95 "},
{"descripcion": " Mascarillaa 3m N95 Por Unidad "},
{"descripcion": null},
{"descripcion": " Mascarilla N95 - 3m "},
{"descripcion": " Respirador N95 Normado Kimberly Clark (mascarilla) "},
{"descripcion": null},
{"descripcion": " Mascarillan95 "},
{"descripcion": " Mascarillas N95 Certificadas "},
{"descripcion": " Mascarilla N95 3m "},
{"descripcion": null},
{"descripcion": " Mascarilla N95 Segre Ffp2 "},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": " Mascarillas 3m N95 Modelo 8210 Certificada "},
{"descripcion": null},
{"descripcion": " Mascarilla N95 "},
{"descripcion": " Mascarillas N95 3m 1860 X Unidades A 43 Soles "},
{"descripcion": null},
{"descripcion": " Venta De Mascarilla 3m N95. "},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": " Mascarilla Respirador N95 X Unidad Gerson Equivale A 3m 8210 "},
{"descripcion": null},
{"descripcion": " Mascarilla 3m N95 1860 Originales S/.70 Unid.y 1100 Caja "},
{"descripcion": " Mascarilla Tipo N 95 C\u00f3nica Caja 50 Unidades "},
{"descripcion": " Mascarilla K N95 Selladas Y Certificada Ce, Fda. "},
{"descripcion": " Mascarilla D95 Selladas Original Tip N95 (entrega Inmediata) "},
{"descripcion": null},
{"descripcion": null},
{"descripcion": null},
{"descripcion": " Mascarilla 3m Respirador 8210 N95 Caja X 20 Unid Orginal "}
]

Пожалуйста, поддержите меня в решении этой проблемы. Приветствия

1 Ответ

0 голосов
/ 23 апреля 2020

Страницы с результатами имеют много элементов, но, используя .get(), вы получаете только первый элемент на странице. Вы должны использовать .getall() с l oop, который yield каждый элемент в отдельном MercadolibreItem()

Для тестов я использовал обычный словарь вместо MercadolibreItem()

def parse_item(self, response):
    #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
    #item['name'] = response.xpath('//div[@id="name"]').get()
    #item['description'] = response.xpath('//div[@id="description"]').get()

    for element in response.xpath('//h2[@class="item__title list-view-item-title"]/a/span/text()').getall():
        item = {}
        #item = MercadolibreItem()
        item['descripcion'] = element
        yield item

Но чтобы получить много значений для каждого элемента, лучше найти объекты, которые хранят элементы (без использования get() или getall(), а затем используют относительный xpath (начиная с точки .) для поиска имени, описания внутри каждого объекта evey отдельно.

Выполняя поиск сначала по всем именам, а затем по всем описаниям, вы можете получить списки с разным количеством элементов (если у какого-либо объекта нет имени или описания), а позже будет сложно сгруппировать имя с описанием в правильные пары.

def parse_item(self, response):
    for element in response.xpath('//li[@class="results-item highlighted article stack item-without-installmets"]'):
        item = {}
        #item = MercadolibreItem()
        item['title'] = element.xpath('.//span[@class="main-title"]//text()').get()
        item['price_symbol'] = element.xpath('.//span[@class="price__symbol"]//text()').get()
        item['price_fraction'] = element.xpath('.//span[@class="price__fraction"]//text()').get()
        yield item

Минимальный рабочий код, который вы можете поместить в один файл и для которого не нужно создавать проект

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
#from mercadolibre.items import MercadolibreItem

class MercadolibreperuSpider(CrawlSpider):
    name = 'mercadolibreperu'
    allowed_domains = ['mercadolibre.com.pe']
    start_urls = ['https://listado.mercadolibre.com.pe/lima/mascarilla-n95_ITEM*CONDITION_2230284']

    rules = (
        #Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
        Rule(
            LinkExtractor(
                restrict_xpaths=(
                    '//section[@id="results-section"]',        
                ),
            ),
            callback='parse_item',
            follow=True
        ),
    )

    def parse_item_old(self, response):
        #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
        #item['name'] = response.xpath('//div[@id="name"]').get()
        #item['description'] = response.xpath('//div[@id="description"]').get()
        for element in response.xpath('//h2[@class="item__title list-view-item-title"]/a/span/text()').getall():
            #item = {}
            item = MercadolibreItem()
            item['descripcion'] = element
            yield item

    def parse_item(self, response):
        #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
        #item['name'] = response.xpath('//div[@id="name"]').get()
        #item['description'] = response.xpath('//div[@id="description"]').get()

        for element in response.xpath('//li[@class="results-item highlighted article stack item-without-installmets"]'):
            item = {}
            #item = MercadolibreItem()
            item['title'] = element.xpath('.//span[@class="main-title"]//text()').get()
            item['price_symbol'] = element.xpath('.//span[@class="price__symbol"]//text()').get()
            item['price_fraction'] = element.xpath('.//span[@class="price__fraction"]//text()').get()
            yield item

from scrapy.crawler import CrawlerProcess

c = CrawlerProcess({
    'USER_AGENT': 'Mozilla/5.0',

    # save in file CSV, JSON or XML
    'FEED_FORMAT': 'csv',     # csv, json, xml
    'FEED_URI': 'output.csv', #
})
c.crawl(MercadolibreperuSpider)
c.start()
...