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!