2014-04-09 3 views
8

Sono principiante in Python e sto utilizzando Scrapy per un progetto Web personale.Utilizzo del middleware per ignorare i duplicati in Scrapy

Uso Scrapy per estrarre ripetutamente i dati da diversi siti Web, quindi è necessario controllare ogni scansione se un collegamento è già presente nel database prima di aggiungerlo. Ho fatto questo in una classe piplines.py:

class DuplicatesPipline(object): 
    def process_item(self, item, spider): 
     if memc2.get(item['link']) is None: 
      return item 
     else: 
      raise DropItem('Duplication %s', item['link']) 

Ma ho sentito che l'utilizzo di Middleware è meglio per questo compito.

Ho trovato un po 'difficile usare Middleware in Scrapy, qualcuno può per piacere reindirizzarmi a un buon tutorial.

i consigli sono benvenuti.

Grazie,

Modifica:

sto usando MySql e memcache.

Qui è la mia prova in base alle @Talvalin risposta:

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

from scrapy.exceptions import IgnoreRequest 
import MySQLdb as mdb 
import memcache 

connexion = mdb.connect('localhost','dev','passe','mydb') 
memc2 = memcache.Client(['127.0.0.1:11211'], debug=1) 

class IgnoreDuplicates(): 

    def __init__(self): 
     #clear memcache object 
     memc2.flush_all() 

     #update memc2 
     with connexion: 
      cur = connexion.cursor() 
      cur.execute('SELECT link, title FROM items') 
      for item in cur.fetchall(): 
       memc2.set(item[0], item[1]) 

    def precess_request(self, request, spider): 
     #if the url is not in memc2 keys, it returns None. 
     if memc2.get(request.url) is None: 
      return None 
     else: 
      raise IgnoreRequest() 

DOWNLOADER_MIDDLEWARES = { 
    'myproject.middlewares.IgnoreDuplicates': 543, 
    'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 500, } 

ma sembra che il metodo process_request viene ignorato durante la scansione.

Grazie in anticipo,

+0

in sostanza, è necessario creare una classe middleware downloader che implementa un metodo 'process_response' e ​​carica i tuoi URL scansione e controlla l'URL della risposta in entrata per vedere se v'è una corrispondenza. http://doc.scrapy.org/en/latest/topics/downloader-middleware.html – Talvalin

+0

Che DB stai usando? – Talvalin

+0

Sto usando MySql e memcache. Grazie per la risposta. – elhoucine

risposta

8

ecco qualche esempio di codice middleware che carica gli URL di una tabella sqlite3 (Id INT, url TEXT) in un set, e quindi controlli richiedere gli URL contro il set per determinare se l'URL dovrebbe essere ignorato o meno. Dovrebbe essere ragionevolmente semplice adattare questo codice per usare MySQL e memcache, ma per favore fatemi sapere se avete problemi o domande. :)

import sqlite3 
from scrapy.exceptions import IgnoreRequest 

class IgnoreDuplicates(): 

    def __init__(self): 
     self.crawled_urls = set() 

     with sqlite3.connect('C:\dev\scrapy.db') as conn: 
      cur = conn.cursor() 
      cur.execute("""SELECT url FROM CrawledURLs""") 
      self.crawled_urls.update(x[0] for x in cur.fetchall()) 

     print self.crawled_urls 

    def process_request(self, request, spider): 
     if request.url in self.crawled_urls: 
      raise IgnoreRequest() 
     else: 
      return None 

Sulla remota possibilità di avere problemi di importazione come me e sono in procinto di pugno il monitor, il codice di cui sopra è stato in un file middlewares.py che è stato inserito nella cartella progetto di primo livello con il seguente DOWNLOADER_MIDDLEWARES impostazione

DOWNLOADER_MIDDLEWARES = { 
    'myproject.middlewares.IgnoreDuplicates': 543, 
    'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 500, 
} 
+0

Ciao Talvalin, ho provato la tua soluzione ma sembra che Scrapy ignori il metodo process_request durante la scansione, quindi non ignora i collegamenti duplicati. Ho controllato la documentazione e ho trovato solo metodi come process_spider_input, process_spider_output .. ma non process_request. Grazie – elhoucine

+1

Quando si esegue lo spider, IgnoreDuplicates viene visualizzato nei log sotto i middleware abilitati? – Talvalin

+0

Penso di si. Eseguo "scrapy crawl nome_progetto" ---------- 2014-04-09 22: 36: 07 + 0100 [scrapy] INFO: Enabled middleware di downloader: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, IgnoreDuplicates, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMiddleware, ChunkedTransferMiddleware, DownloaderStats 2014/04/09 22: 36: 07 + 0100 [Scrapy] INFORMAZIONI: Attivato middleware ragno: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware – elhoucine