Manipulando Dados
Após uma spider extrair os dados, as informações são contidas em um item (uma estrutura de dados predefinida no Scrapy) e são enviadas ao Item Pipeline para processá-las.
Um pipeline de itens é uma classe Python definida em pipelines.py que implementa o método process_item(self, item, spider). Ele recebe um item, processa e decide se o item deve continuar passando pelos próximos componentes do pipeline ou se deve ser descartado e não mais processado.
Alguns usos comuns dos pipelines de itens são:
- Limpeza de dados HTML: Remover tags HTML indesejadas ou conteúdo desnecessário dos dados extraídos.
- Validação de dados extraídos: Verificar se os itens contêm os campos necessários ou se os dados seguem um formato específico.
- Verificação de duplicatas: Identificar e eliminar itens duplicados.
- Armazenamento dos itens extraídos: Salvar os dados raspados em um banco de dados ou outro tipo de armazenamento.
No contexto do nosso projeto, teremos pipelines para lidar com conversão do preço de dólar para real e salvar os dados dos produtos no banco de dados SQLite.
Criando pipelines
Por padrão, o Scrapy gera no projeto um arquivo pipelines.py:
from itemadapter import ItemAdapter
class TutorialPipeline:
def process_item(self, item, spider):
return item
Cada pipeline deve implementar os seguintes métodos:
process_item: É chamado para cada componente do pipeline de itens
open_spider: É chamado quando a spider é executada
close_spider: É chamado quando a spider finaliza a execução
Agora que sabemos o que é uma pipeline e a base de seu funcionamento, vamos criar uma pipeline que converte o preço do produto de dolár(USD) para real(BRL).
from scrapy.exceptions import DropItem
class PriceConversionToBRLPipeline:
usd_to_brl_conversion_factor = 5.65 # (1)!
def process_item(self, item, spider):
adapter = ItemAdapter(item) # (2)!
if adapter.get('price'): # (3)!
try:
price_in_usd = float(adapter['price']) # (4)!
adapter['price'] = price_in_usd * self.usd_to_brl_conversion_factor # (5)!
except (ValueError, IndexError): # (6)!
raise DropItem(f"Price format error in {item}")
return item
else:
raise DropItem(f'Missing price in {item}') # (7)!
- Taxa de conversão de USD para BRL. 1 USD = R$ 5.65
- Cria um objeto ItemAdapter que envolve o item extraídos pela spider
- Verifica se o campo 'price' existe no item
- Converte a parte numérica para float
- Aplica a taxa de conversão para real(BRL)
- Indica se ocorrer um ValueError(na conversão do preço) ou um IndexError(na extração do preço)
- Se o item não tiver o campo 'price', ele é descartado
Código completo das pipelines:
from itemadapter import ItemAdapter
from scrapy.exceptions import DropItem
class PriceConversionToBRLPipeline:
usd_to_brl_conversion_factor = 5.65
def process_item(self, item, spider):
adapter = ItemAdapter(item)
if adapter.get('price'):
try:
price_in_usd = float(adapter['price'])
adapter['price'] = price_in_usd * self.usd_to_brl_conversion_factor
except (ValueError, IndexError):
raise DropItem(f"Price format error in {item}")
return item
else:
raise DropItem(f'Missing price in {item}')
Vamos executar a spider e analisar o log de execução:
Ops! Pelo log podemos ver que a pipeline que criamos não está sendo executada. E os preços dos produtos continuam em dólar.
Faltou um detalhe: Precisamos informar ao Scrapy que temos a pipeline PriceConversionToBRLPipeline no projeto.
Configurando Pipeline
No arquivo settings.py vamos habilitar e configurar ITEM_PIPELINES informando o caminho do módulo da pipeline e a prioridade na ordem de execução.
ITEM_PIPELINES = {
"tutorial.pipelines.PriceConversionToBRLPipeline": 300,
}
Pipelines com números menores são executados primeiro. Por exemplo, pipelines com valor 100 são executados antes de pipelines com valor 300.
Vamos executar novamente a spider e analisar o log de execução:
Agora sim! Pipeline habilitada e preços sendo convertidos para real! Parabéns! Mais um requisito solicitado pelo cliente foi atendido com sucesso!