Scrapy Spider'da kullanıcı tanımlı bir argüman nasıl iletilir


100

Bir hurdacı örümceğine kullanıcı tanımlı bir argüman geçirmeye çalışıyorum. Bunun nasıl yapılacağı konusunda kimse önerebilir mi?

Bir -ayerde bir parametre okudum ama nasıl kullanılacağı hakkında hiçbir fikrim yok.

Yanıtlar:


189

Örümcek argümanları crawl, -aseçenek kullanılarak komutta iletilir . Örneğin:

scrapy crawl myspider -a category=electronics -a domain=system

Örümcekler argümanlara nitelik olarak erişebilir:

class MySpider(scrapy.Spider):
    name = 'myspider'

    def __init__(self, category='', **kwargs):
        self.start_urls = [f'http://www.example.com/{category}']  # py36
        super().__init__(**kwargs)  # python3

    def parse(self, response)
        self.log(self.domain)  # system

Scrapy belgesinden alınmıştır: http://doc.scrapy.org/en/latest/topics/spiders.html#spider-arguments

2013 Güncellemesi : İkinci argüman ekle

2015 Güncellemesi : İfadeleri ayarlayın

2016 Güncellemesi : Daha yeni temel sınıf kullanın ve süper ekleyin, teşekkürler @Birla

2017 Güncellemesi : Python3 super kullanın

# previously
super(MySpider, self).__init__(**kwargs)  # python2

2018 Güncelleme : As @eLRuLL işaret , örümcekler nitelikler olarak argümanlar erişebilir


3
hurda tarama myspider -a kategori = elektronik -a etki alanı = sistem
Steven Almeroth

1
Yukarıdaki kod sadece kısmen benim için çalışıyor. Örneğin. Etki alanını kullanarak tanımlarsam self.domain, __init__yöntemin dışında ona hala erişemiyorum . Python tanımlanmamış bir hata atar. BTW, superaramayı neden ihmal ettin ? PS. CrawlSpider sınıfıyla çalışıyorum
Birla

2
@FlyingAtom Yanlış anladıysam lütfen beni düzeltin, ancak bu eşzamanlı çağrıların her biri örümceğin farklı örnekleri olurdu, değil mi?
L Lawliet

1
@Birla, sınıf kapsam değişkenini doldurmak için yapıcıda self.domain = domain kullanın.
Hassan Raza

1
@nealmcb __init__, örümcek sınıfının bir yöntemidir . Uygulanması, örümceği daha az sağlam yapmaz ve anahtar kelime argümanları için varsayılanları açıklayabileceğinizi ancak söylediğiniz gibi isteğe bağlı olduğunu göstermek için yanıta dahil edilir. Geçen yıl belirttiğimiz getattrgibi, argümanlara nitelik olarak sadece erişebilirsiniz, örneğin self.categoryya da cevapta gördüğümüz gibiself.domain
Steven Almeroth

32

Önceki cevaplar doğruydu, ancak __init__bir hurdacı örümceğini her kodlamak istediğinizde yapıcıyı ( ) bildirmek zorunda değilsiniz , parametreleri önceden olduğu gibi belirtebilirsiniz:

scrapy crawl myspider -a parameter1=value1 -a parameter2=value2

ve örümcek kodunuzda bunları örümcek argümanları olarak kullanabilirsiniz:

class MySpider(Spider):
    name = 'myspider'
    ...
    def parse(self, response):
        ...
        if self.parameter1 == value1:
            # this is True

        # or also
        if getattr(self, parameter2) == value2:
            # this is also True

Ve sadece çalışıyor.


4
Doğru. Python'un karanlık tarafına girin.
Barney

14

Değişkenleri crawl komutuyla geçirmek için

hurda tarama myspider -a kategori = 'kategorim' -a etki alanı = 'örnek.com'

Scrapyd üzerinde çalıştırılacak bağımsız değişkenleri iletmek için -a yerine -d

kıvırmak http://your.ip.address.here:port/schedule.json -d örümcek = myspider -d kategori = 'kategorim' -d etki alanı = 'örnek.com'

Örümcek, kurucusunda argümanlar alacak.


class MySpider(Spider):
    name="myspider"
    def __init__(self,category='',domain='', *args,**kwargs):
        super(MySpider, self).__init__(*args, **kwargs)
        self.category = category
        self.domain = domain

Scrapy tüm argümanları örümcek nitelikleri olarak koyar ve init metodunu tamamen atlayabilirsiniz . Bu öznitelikleri almak için getattr yöntemini kullanmaya dikkat edin, böylece kodunuz bozulmaz .


class MySpider(Spider):
    name="myspider"
    start_urls = ('https://httpbin.org/ip',)

    def parse(self,response):
        print getattr(self,'category','')
        print getattr(self,'domain','')

Kısa, sağlam ve esnek!
nealmcb

8

-A seçeneği kullanılarak crawl komutu çalıştırılırken Spider argümanları iletilir. Örneğin, örümceğime argüman olarak bir alan adı geçirmek istersem, bunu yapacağım-

hurda tarama myspider -a etki alanı = "http://www.example.com"

Ve örümcek kurucularından argümanlar alın:

class MySpider(BaseSpider):
    name = 'myspider'
    def __init__(self, domain='', *args, **kwargs):
        super(MySpider, self).__init__(*args, **kwargs)
        self.start_urls = [domain]
        #

...

Çalışacak :)


0

Alternatif olarak , start_url ve spider adını iletebileceğimiz bir API ortaya çıkaran ScrapyD'yi kullanabiliriz . ScrapyD'nin örümcekleri durdurması / başlatması / durumu / listelemesi için API'leri vardır.

pip install scrapyd scrapyd-deploy
scrapyd
scrapyd-deploy local -p default

scrapyd-deployörümceği yumurta şeklinde daemon içine yerleştirir ve hatta örümcek versiyonunu korur. Örümceği başlatırken, örümceğin hangi versiyonunu kullanacağınızı belirtebilirsiniz.

class MySpider(CrawlSpider):

    def __init__(self, start_urls, *args, **kwargs):
        self.start_urls = start_urls.split('|')
        super().__init__(*args, **kwargs)
    name = testspider

curl http://localhost:6800/schedule.json -d project=default -d spider=testspider -d start_urls="https://www.anyurl...|https://www.anyurl2"

Ek bir avantaj, kullanıcının url ve diğer parametrelerini kabul etmek ve yukarıdaki scrapyd zamanlama API'sini kullanarak bir görev planlamak için kendi kullanıcı arayüzünüzü oluşturabilmenizdir.

Daha fazla ayrıntı için scrapyd API belgelerine bakın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.