Scrapy использует CSS для извлечения данных и превосходного экспорта всего в одну ячейку - PullRequest
0 голосов
/ 08 февраля 2020

Вот паук

import scrapy
import re

from ..items import HomedepotSpiderItem



class HomedepotcrawlSpider(scrapy.Spider):
    name = 'homeDepotCrawl'
    allowed_domains = ['homedepot.com']
    start_urls = ['https://www.homedepot.com/b/ZLINE-Kitchen-and-Bath/N-5yc1vZhsy/Ntk-ProductInfoMatch/Ntt-zline?NCNI-5&storeSelection=3304,3313,3311,3310,8560&experienceName=default']



    def parse(self, response):

        items = HomedepotSpiderItem()

        #get model
        productName = response.css('.pod-plp__description.js-podclick-analytics').css('::text').getall()

        productName = [x.strip(' ') for x in productName if len(x.strip())] 
        productName = [x.strip('\n') for x in productName if len(x.strip())] 
        productName = [x.strip('\t') for x in productName if len(x.strip())] 
        productName = [x.strip(',') for x in productName if len(x.strip())] 

        #productName = productName[0].split(',') tried to split the list into indiviudal elements


        productSKU = response.css('.pod-plp__model::text').getall()

        #get rid of all the stuff i dont need
        productSKU = [x.strip(' ') for x in productSKU] #whiteSpace
        productSKU = [x.strip('\n') for x in productSKU] 
        productSKU = [x.strip('\t') for x in productSKU] 
        productSKU = [x.strip(' Model# ') for x in productSKU] #gets rid of the model name 
        productSKU = [x.strip('\xa0') for x in productSKU] #gets rid of the model name 


        #get the price
        productPrice = response.css('.price__numbers::text').getall()

        #get rid of all the stuff i dont need
        productPrice = [x.strip(' ') for x in productPrice if len(x.strip())] 
        productPrice = [x.strip('\n') for x in productPrice if len(x.strip())] 
        productPrice = [x.strip('\t') for x in productPrice if len(x.strip())] 
        productPrice = [x.strip('$') for x in productPrice if len(x.strip())] 

        ## All prices are printing out twice, so take every other price
        productPrice = productPrice[::2]



        items['productName'] = productName
        items['productSKU'] = productSKU
        items['productPrice'] = productPrice

        yield items

Items.py

import scrapy


class HomedepotSpiderItem(scrapy.Item):
     #create items
     productName = scrapy.Field()
     productSKU = scrapy.Field()
     productPrice = scrapy.Field()
     #prodcutNumRating = scrapy.Field()

     pass

Мой выпуск

Я сейчас практикуюсь со Scrapy и извлек все эти данные с сайта Home Depot, используя CSS. После извлечения я вручную удалил все данные, которые мне не нужны, и на терминале все выглядело нормально. Однако, после экспорта всего, что нужно, все мои извлеченные данные распечатываются в один столбец на строку. Пример: Product Name -> все модели, входящие в одну ячейку. Я посмотрел документацию по scrapy и увидел, что .getall () возвращает все в виде списка, поэтому я попытался разбить список на отдельные элементы, думая, что все будет в порядке. это избавило бы от всех данных, которые я очистил.

Любая помощь будет признательна, и дайте мне знать, если есть какие-либо разъяснения, которые необходимы!

Редактировать Я экспортирую в Excel, используя: scrapy crawl homeDepotCrawl -o test.csv -t csv

1 Ответ

2 голосов
/ 08 февраля 2020

Проблема в том, что вы загружаете все элементы в один экземпляр scrapy.Item. См. Комментарии к коду для получения более подробной информации.

Кроме того, стоит отметить, что вы можете использовать загрузчики элементов или создавать конвейер элементов для очистки полей вместо повторения такого большого количества кода. При работе с одним предметом вам не нужно будет использовать такое понимание списка. Даже простая функция, которую вы можете вызвать, чтобы запустить их, была бы лучше, чем выполнение всего этого понимания списка.

[1] https://docs.scrapy.org/en/latest/topics/loaders.html

[2] https://docs.scrapy.org/en/latest/topics/item-pipeline.html

[3] https://docs.scrapy.org/en/latest/topics/items.html

import scrapy
import re

from ..items import HomedepotSpiderItem

class HomedepotcrawlSpider(scrapy.Spider):
    name = 'homeDepotCrawl'
    allowed_domains = ['homedepot.com']
    start_urls = ['https://www.homedepot.com/b/ZLINE-Kitchen-and-Bath/N-5yc1vZhsy/Ntk-ProductInfoMatch/Ntt-zline?NCNI-5&storeSelection=3304,3313,3311,3310,8560&experienceName=default']


def parse(self, response):
    '''
    Notice when we set items variable we are not using .get or .extract yet
    We collect the top level of each item into a list of selectors. 
    Then we loop through the selectors creating a new scrapy.Item instance for each selector/item on the page. 
    The for product in items loop will step through each item selector individually.
    You can then chain .css to your variable product.css now to access each section of each 
    item individually and export them separately. 
    This will give you a new row for each item.
    '''
    items = response.css('.plp-pod')
    for product in items:
        # Create new scrapy.Item for each product in our selector list.
        item = HomedepotSpiderItem()
        item['productName'] = product.css('.pod-plp__description.js-podclickanalytics::text').get()
        # Notice we are yielding item inside of the loop.
        yield item
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...