2012-10-21 16 views
24

ich einen Arbeits Crawler mit scrapy geschrieben haben,
jetzt habe ich es durch eine Django Webapp steuern möchten, das heißt:Wie Setup und starten Sie programmatisch eine Scrapy Spinne (URLs und Einstellungen)

  • Set 1 oder mehrere start_urls
  • Set 1 oder mehrere allowed_domains
  • Set settings Werte
  • Starten Sie die Spinne
  • Stopp/Pause/Fortsetzen einer Spinne
  • rufen Sie einige Statistiken während des Laufens
  • retrive einige Statistiken nach Spider abgeschlossen ist.

Zuerst dachte ich scrapyd dafür gemacht wurde, aber nach dem Doc lesen, scheint es, dass es mehr ein Dämon der Lage ‚verpackt Spinnen‘, auch bekannt als ‚scrapy Eier‘ zu verwalten; und dass alle Einstellungen (start_urls, allowed_domains, settings) immer noch in dem "Scrapy Ei" selbst fest programmiert sein müssen; Es sieht also nicht nach einer Lösung für meine Frage aus, es sei denn, ich habe etwas übersehen.

Ich schaute auch auf diese Frage: How to give URL to scrapy for crawling?; Aber die beste Antwort, um mehrere URLs zur Verfügung zu stellen, wird vom Autor himeslf als 'hässlicher Hack' eingestuft, der einen Python-Subprozess und eine komplexe Shell-Behandlung beinhaltet, daher glaube ich nicht, dass die Lösung hier zu finden ist. Es funktioniert möglicherweise auch für start_urls, aber es scheint nicht zu ermöglichen, allowed_domains oder settings.

Dann warf ich einen Blick auf scrapy webservices: Es scheint die gute Lösung für das Abrufen von Statistiken zu sein. Allerdings ist es immer noch eine Laufspinne erfordert, und keine Ahnung zu ändern settings

Es gibt eine Reihe von Fragen zu diesem Thema sind, keiner von ihnen scheint zufrieden stellend:

Ich weiß, dass Scrapy in Produktionsumgebungen verwendet wird; und ein Tool wie scrapyd zeigt, dass es definitiv einige Möglichkeiten gibt, diese Anforderungen zu bewältigen (ich kann mir nicht vorstellen, dass die scrapy Eier, mit denen scrapyd zu tun hat, mit der Hand erzeugt werden!)

Vielen Dank für Ihre Hilfe.

+0

Scrapy Eier werden mit dem 'deploy' Befehl erstellt; Vielleicht können Sie den [Django Dynamic Scraper] (https://github.com/holgerd77/django-dynamic-scraper) für Hinweise zur Integration der Scrapy Spider Steuerung in Django besuchen. –

+0

Haben Sie sich das [scrapy tool] (http://doc.scrapy.org/en/latest/topics/commands.html) oder das [slybot project] (https://github.com/scrapy/slybot) angesehen Inspiration? – jah

+0

Meine Antwort http://stackoverflow.com/questions/9814827/creating-a-generic-scrapy-spider/13054768#13054768 kann helfen – djinn

Antwort

0

Ich glaube, Sie an diesem

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

suchen müssen Dies tut etwas ähnlich, was Sie wollen. Es verwendet auch den Sellerie der Aufgabe sheduling. Sie können den Code sehen, um zu sehen, was er macht.Ich denke, dass es leicht sein wird, wenn Sie den Code ändern zu tun, was Sie

wollen Es hat auch gute docs, wie die Einrichtung der Schnittstelle mit django

9

Zuerst dachte ich, scrapyd dafür gemacht wurde, aber Nach dem Lesen des Dokuments scheint es, dass es eher ein Daemon ist, der "verpackte Spinnen", auch bekannt als "scrapy eggs", verwalten kann. und dass alle Einstellungen (start_urls, allowed_domains, settings) im "scrapy egg" selbst noch fest codiert sein müssen; Es sieht also nicht nach einer Lösung für meine Frage aus, es sei denn, ich habe etwas übersehen.

ich auf die obige Aussage nicht einverstanden sind, start_urls nicht hart codiert werden müssen, können sie dynamisch an die Klasse übergeben werden, sollten Sie in der Lage sein, es wie dieses

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

Oder Sie sollten in der Lage sein, die URLs aus einer Datenbank oder Datei abzurufen. Ich bekomme es von einer Datenbank wie diesem

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

Das ist eigentlich wirklich einfach!

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

Ist es auch möglich, allowed_domains in Runtime anzugeben? –

6

Für Einstellungen programmatisch und den Betrieb der Schaber aus innerhalb einer App verändert, ist hier, was ich habe:

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() 
Verwandte Themen