2012-10-21 14 views
24

Ho scritto un cingolato di lavoro utilizzando Scrapy,
ora voglio controllarlo attraverso una webapp Django, vale a dire:Come configurare e lanciare un ragno Scrapy di programmazione (URL e impostazioni)

  • Set 1 o più start_urls
  • Set 1 o più allowed_domains
  • Set settings valori
  • Avviare il ragno
  • Stop/pausa/ripresa di un ragno
  • recuperare alcune statistiche mentre è in esecuzione
  • recuperare alcune statistiche dopo che lo spider è completo.

In un primo momento ho pensato scrapyd è stato fatto per questo, ma dopo aver letto il documento, sembra che sia più un demone in grado di gestire 'i ragni confezionati', alias 'uova Scrapy'; e che tutte le impostazioni (start_urls, allowed_domains, settings) devono ancora essere codificate nel "egg scrapy" stesso; quindi non sembra una soluzione alla mia domanda, a meno che non mi sia sfuggito qualcosa.

Ho anche esaminato questa domanda: How to give URL to scrapy for crawling?; Ma la migliore risposta per fornire più url è qualificata dall'autore come un "brutto hacking", che coinvolge alcuni subprocessi python e una complessa gestione della shell, quindi non penso che la soluzione sia trovata qui. Inoltre, potrebbe funzionare per start_urls, ma non sembra consentire allowed_domains o settings.

Quindi ho dato un'occhiata a scrapy webservices: Sembra essere la buona soluzione per il recupero delle statistiche. Tuttavia, esso richiede comunque un ragno in esecuzione, e nessun indizio di cambiare settings

Ci sono diverse domande su questo argomento, nessuno di loro sembra soddisfacente:

So che lo scrapy è utilizzato negli ambienti di produzione; e uno strumento come scrapyd mostra che ci sono sicuramente alcuni modi per gestire questi requisiti (non riesco a immaginare che le uova di scrapy scrapyd trattate siano generate a mano!)

Grazie mille per il vostro aiuto.

+0

Scrapy vengono creati con il comando 'deploy'; forse puoi dare un'occhiata a [Django Dynamic Scraper] (https://github.com/holgerd77/django-dynamic-scraper) per suggerimenti su come integrare il controllo Spider Scrapy in Django. –

+0

Hai guardato [scrapy tool] (http://doc.scrapy.org/en/latest/topics/commands.html) o il [progetto slybot] (https://github.com/scrapy/slybot) per ispirazione? – jah

+0

La mia risposta http://stackoverflow.com/questions/9814827/creating-a-generic-scrapy-spider/13054768#13054768 potrebbe aiutare – djinn

risposta

0

Penso che avete bisogno di guardare a questo

http://django-dynamic-scraper.readthedocs.org/en/latest/

Questo fa in qualche modo simile ciò che si desidera. Usa anche il sedano di sheduling di compiti. Puoi vedere il codice per dare un'occhiata a quello che sta facendo.Penso che sarà facile se si modifica il suo codice per fare quello che vuoi

Ha anche una buona documentazione su come configurare l'interfaccia con Django

9

In un primo momento ho pensato che scrapyd è stato fatto per questo, ma dopo aver letto il documento, sembra che sia più un daemon in grado di gestire gli "spider pacchettizzati", alias "uova di carta straccia"; e che tutte le impostazioni (start_urls, allowed_domains, settings) devono ancora essere codificate nel "egg scrapy" stesso; quindi non sembra una soluzione alla mia domanda, a meno che non mi sia sfuggito qualcosa.

non sono d'accordo per la dichiarazione di cui sopra, start_urls non devono essere codificati che possono essere passati in modo dinamico alla classe, si dovrebbe essere in grado di passare come argomento come questo

http://localhost:6800/schedule.json -d project=myproject -d spider=somespider -d setting=DOWNLOAD_DELAY=2 -d arg1=val1 

Oppure dovresti riuscire a recuperare gli URL da un database o da un file. Ho capito da un database come questo

class WikipediaSpider(BaseSpider): 
    name = 'wikipedia' 
    allowed_domains = ['wikipedia.com'] 
    start_urls = [] 

    def __init__(self, name=None, url=None, **kwargs): 
     item = MovieItem() 
     item['spider'] = self.name 
     # You can pass a specific url to retrieve 
     if url: 
      if name is not None: 
       self.name = name 
      elif not getattr(self, 'name', None): 
       raise ValueError("%s must have a name" % type(self).__name__) 
      self.__dict__.update(kwargs) 
      self.start_urls = [url] 
     else: 
      # If there is no specific URL get it from Database 
      wikiliks = # < -- CODE TO RETRIEVE THE LINKS FROM DB --> 
      if wikiliks == None: 
       print "**************************************" 
       print "No Links to Query" 
       print "**************************************" 
       return None 

      for link in wikiliks: 
       # SOME PROCESSING ON THE LINK GOES HERE 
       self.start_urls.append(urllib.unquote_plus(link[0])) 

    def parse(self, response): 
     hxs = HtmlXPathSelector(response) 
     # Remaining parse code goes here 
2

Questo è in realtà molto semplice!

from mypackage.spiders import MySpider 
from scrapy.crawler import CrawlerProcess 

results = [] 

class MyPipeline(object): 
    """ A custom pipeline that stores scrape results in 'results'""" 
    def process_item(self, item, spider): 
     results.append(dict(item)) 

process = CrawlerProcess({ 
    # An example of a custom setting 
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 
    'ITEM_PIPELINES': {'__main__.MyPipeline': 1}, # Hooking in our custom pipline above 
}) 

start_urls=[ 
    'http://example.com/page1', 
    'http://example.com/page2', 
] 
process.crawl(MySpider, start_urls=start_urls) 
process.start() # the script will block here until the crawling is finished 

# Do something with the results 
print results 
+0

È anche possibile specificare allowed_domains in runtime? –

6

Per modificare le impostazioni di programmazione e l'esecuzione del raschietto all'interno di un app, ecco cosa ho ottenuto: uova

from scrapy.crawler import CrawlerProcess 
from myproject.spiders import MySpider 
from scrapy.utils.project import get_project_settings 

os.environ['SCRAPY_SETTINGS_MODULE'] = 'myproject.my_settings_module' 
scrapy_settings = get_project_settings() 
scrapy_settings.set('CUSTOM_PARAM', custom_vaule) 
scrapy_settings.set('ITEM_PIPELINES', {}) # don't write jsons or anything like that 
scrapy_settings.set('DOWNLOADER_MIDDLEWARES', { 
    'myproject.middlewares.SomeMiddleware': 100, 
}) 
process = CrawlerProcess(scrapy_settings) 
process.crawl(MySpider, start_urls=start_urls) 
process.start() 
Problemi correlati