Поток данных Scrapy и загрузчики предметов и предметов - PullRequest
0 голосов
/ 29 июня 2018

Я просматриваю страницу Обзор архитектуры в документации Scrapy, но у меня все еще есть несколько вопросов, касающихся данных и / или потока управления.

Scrapy Architecture enter image description here

Файловая структура проектов Scrapy по умолчанию

scrapy.cfg
myproject/
    __init__.py
    items.py
    middlewares.py
    pipelines.py
    settings.py
    spiders/
        __init__.py
        spider1.py
        spider2.py
    ...

item.py

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

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

import scrapy

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

которое, я полагаю, становится

import scrapy

class Product(scrapy.Item):
    name = scrapy.Field()
    price = scrapy.Field()
    stock = scrapy.Field()
    last_updated = scrapy.Field(serializer=str)

, чтобы при попытке заполнить необъявленные поля Product экземпляров

возникают ошибки
>>> product = Product(name='Desktop PC', price=1000)
>>> product['lala'] = 'test'
Traceback (most recent call last):
    ...
KeyError: 'Product does not support field: lala'

Вопрос № 1

Где, когда и как наш сканер узнает о items.py, если мы создали class CrowdfundingItem в items.py?

Это сделано в ...

  • __init__.py
  • my_crawler.py
  • def __init__() из mycrawler.py?
  • settings.py
  • pipelines.py
  • def __init__(self, dbpool) из pipelines.py?
  • где-то еще?

Вопрос № 2

Как только я объявил элемент, такой как Product, как мне сохранить данные, создав экземпляры Product в контексте, аналогичном приведенному ниже?

import scrapy

class MycrawlerSpider(CrawlSpider):
    name = 'mycrawler'
    allowed_domains = ['google.com']
    start_urls = ['https://www.google.com/']
    def parse(self, response):
        options = Options()
        options.add_argument('-headless')
        browser = webdriver.Firefox(firefox_options=options)
        browser.get(self.start_urls[0])
        elements = browser.find_elements_by_xpath('//section')
        count = 0
        for ele in elements:
             name = browser.find_element_by_xpath('./div[@id="name"]').text
             price = browser.find_element_by_xpath('./div[@id="price"]').text

             # If I am not sure how many items there will be,
             # and hence I cannot declare them explicitly,
             # how I would go about creating named instances of Product?

             # Obviously the code below will not work, but how can you accomplish this?

             count += 1
             varName + count = Product(name=name, price=price)
             ...

Наконец, скажем, мы вообще отказались от именования экземпляров Product, а вместо этого просто создаем безымянные экземпляры.

for ele in elements:
    name = browser.find_element_by_xpath('./div[@id="name"]').text
    price = browser.find_element_by_xpath('./div[@id="price"]').text
    Product(name=name, price=price)

Если такие экземпляры действительно где-то хранятся, где они хранятся? Создавая экземпляры таким образом, было бы невозможно получить к ним доступ?

1 Ответ

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

Использование Item необязательно; это просто удобный способ объявить вашу модель данных и применить проверку. Вместо этого вы также можете использовать простой dict.

Если вы решите использовать Item, вам нужно будет импортировать его для использования в пауке. Это не обнаружено автоматически. В вашем случае:

from items import CrowdfundingItem

Когда паук запускает метод parse на каждой странице, вы можете загрузить извлеченные данные в Item или dict. Как только он загружен, yield он передает его обратно в механизм очистки для последующей обработки, в конвейерах или экспортерах. Так скрап позволяет «хранить» данные, которые вы скребете.

Например:

yield Product(name='Desktop PC', price=1000) # uses Item
yield {'name':'Desktop PC', 'price':1000} # plain dict
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...