O post vai descrever um spider básico que lista em um JSON todos os tópicos criados nas duas primeiras páginas do site guj.com.br.
Ambiente:
- Ubuntu 14.04
- Sublime text
Ferramentas utilizadas:
- Scrapy
- Python
- virtualenv
# Instalando e criando ambiente virutalenv
Para quem não conhece, virtualenv é uma ferramenta que isola seu ambiente. Muito útil para quem trabalha com mais de um projeto na mesma máquina ou para resolver problemas de permissões.
* Instalando virtualenv
$sudo pip install virtualenv
* Criando um novo ambiente
$virtualenv NomeDoAmbiente
* Ativando ambiente
$source ./NomeDoAmbiente/bin/activate
# Instalando scrapy no ambiente virtualenv
$sudo apt-get install libxml2-dev libxslt-dev $sudo apt-get install python-lxml $pip install scrapy
* Verificando instalação do scrapy, o comando abaixo deve exibir o caminho para o seu virtualenv
$which scrapy
Caso o comando não exiba o scrapy do virtualenv, você pode forçar a execução do scrapy apontando para bin/scrapy
# Criando novo projeto com scrapy
$scrapy startproject nomedoprojeto
# Criando spider com template basico
$scrapy genspider java guj.com.br
# Adicionando alguns parâmetros ao arquivo de settins.py
#para nao sobre carregar o site DOWNLOAD_DELAY = 5 # evitar looping de recursividade REDIRECT_MAX_TIMES = 5 #para evitar acesso remoto TELNETCONSOLE_ENABLED = False #definindo os pipelines ITEM_PIPELINES = { 'guj.pipelines.GujPipeline': 300, 'guj.pipelines.JsonWithEncodingPipeline': 800 }# Abaixo vamos alterar a classe de parser chamada pelo scrapy para extrair título dos posts do Guj
# -*- coding: utf-8 -*- import scrapy from guj.items import GujItem #from scrapy.contrib.spiders import CrawlSpider, Rule #from scrapy.contrib.linkextractors import LinkExtractor class JavaSpider(scrapy.Spider): name = "java" allowed_domains = ["guj.com.br"] #navega pelas duas primeiras páginas do guj start_urls = ['http://www.guj.com.br/?p=%s' % page for page in xrange(0,2)] #rules = (Rule(LinkExtractor(allow=('/?p=', )), callback='parse_item'),) def parse(self, response): self.log('url: %s' % response.url) for a in response.xpath('/html/body/div/section/ol/li/div/div/h3/a/text()'): item = GujItem() item['title'] = a.extract() yield item# Agora vamos definir os pipelines de tratamento após a captura do Item
# -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html import json import codecs class GujPipeline(object): def process_item(self, item, spider): #remove os caracteres \n e \t item['title'] = item['title'].replace('\n','') item['title'] = item['title'].replace('\t','') return item class JsonWithEncodingPipeline(object): def __init__(self): self.file = codecs.open('scraped_data_utf8.json', 'w', encoding='utf-8') #pipeline para codificar o JSON extraido do scrapy para UTF-8, pois o scrapy cria #o json no padrão unicode def process_item(self, item, spider): line = json.dumps(dict(item), ensure_ascii=False) + "\n" self.file.write(line) return item def spider_closed(self, spider): self.file.close()# Rodando nosso scrapy passando o parâmetro -o e o nome do json de destino. O comando deve ser executado na pasta do arquivo scrapy.cfg:
$scrapy crawl java -o items.json
GitHub com o source completo do projeto
Olá!
ResponderExcluirLegal o tutorial, bela iniciativa! :)
Um detalhezinho: o arquivo de configuração é settings.py (Python), e não XML. ;)
Acredito que você possa não precisar do pipeline se mudar um pouquinho a expressão XPath, tipo:
response.xpath('normalize-whitespace(//section//h3/a)')
Valeu, happy scraping! ;)
Muito obrigado pelas dicas e por comentar Elias :)
ExcluirAbraço!