スクレイピースパイダーでユーザー定義の引数を渡す方法


100

ユーザー定義の引数をスクレイピースパイダーに渡そうとしています。誰でもそれを行う方法について提案できますか?

-aどこかでパラメータについて読みましたが、その使用方法がわかりません。

回答:


188

スパイダー引数はcrawl-aオプションを使用してコマンドで渡されます。例えば:

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

クモは属性として引数にアクセスできます:

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ドキュメントから取得:http ://doc.scrapy.org/en/latest/topics/spiders.html#spider-arguments

2013年更新:2番目の引数を追加

2015年更新:表現を調整する

2016年の更新:新しい基本クラスを使用し、スーパーを追加します。@ Birlaに感謝

2017年更新:Python3 superを使用する

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

2018年の更新@eLRuLLが指摘するように、スパイダーは属性として引数にアクセスできます


3
スクレイピークロールmyspider -a category = electronics -a domain = system
Steven Almeroth 2013年

1
上記のコードは私にとって部分的にしか機能していません。たとえば を使用してドメインを定義した場合self.domainでも、__init__メソッドの外部からアクセスすることはできません。Pythonは未定義のエラーをスローします。ところで、なぜあなたはsuper呼び出しを省略したのですか?PS。私はCrawlSpiderクラスで作業しています
Birla

2
@FlyingAtom誤解した場合は修正してください。ただし、これらの同時呼び出しはそれぞれ、スパイダーの異なるインスタンスになりますよね。
L Lawliet、2015

1
@Birla、コンストラクタでself.domain = domainを使用して、クラススコープ変数を設定します。
Hassan Raza

1
@nealmcb __init__は、spiderクラスのメソッドです。その実装自体はスパイダーの堅牢性を低下させるものではなく、キーワード引数のデフォルトを宣言できることを示すために回答に含まれていますが、これはオプションです。昨年指摘したように、使用getattrする必要はありません。属性として引数にアクセスすることができます。たとえばself.category、回答にあるようにself.domain
Steven Almeroth

31

以前の答えは正しかったが__init__、スクレイピーのスパイダーをコーディングするたびにコンストラクター()を宣言する必要はなく、以前のようにパラメーターを指定するだけでよい:

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

そしてあなたのスパイダーコードでは、それらをスパイダー引数として使用することができます:

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

そして、それはうまくいきます。


4
そうだね。Pythonのダークサイドに入ります。
Barney

14

クロールコマンドで引数を渡すには

スクレイピークロールmyspider -a category = 'mycategory' -a domain = 'example.com'

引数を渡してscrapydで実行するには、-a-dに置き換えます

curl http://your.ip.address.here:port/schedule.json -d spider = myspider -d category = 'mycategory' -d domain = 'example.com'

スパイダーはコンストラクターで引数を受け取ります。


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はすべての引数をスパイダー属性として配置し、initメソッドを完全にスキップできます。これらの属性を取得するにはgetattrメソッドを使用して、コードが壊れないように注意してください。


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

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


簡潔、堅牢、そして柔軟!
nealmcb

8

-aオプションを使用してクロールコマンドを実行すると、スパイダー引数が渡されます。たとえば、ドメイン名を引数としてスパイダーに渡したい場合、これを行います-

スクレイピークロールmyspider -a domain = "http://www.example.com"

そしてスパイダーのコンストラクタで引数を受け取ります:

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

...

それが動作します :)


0

あるいは、start_urlとスパイダー名を渡すことができるAPIを公開するScrapyDを使用できます。ScrapyDには、スパイダーを停止/開始/ステータス/リストするAPIがあります。

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

scrapyd-deployデーモンにスパイダーを卵の形で展開し、スパイダーのバージョンを維持します。スパイダーを開始するときに、使用するスパイダーのバージョンを指定できます。

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"

追加の利点は、独自のUIを構築して、ユーザーからのURLおよびその他のパラメーターを受け入れ、上記のスクラップスケジュールAPIを使用してタスクをスケジュールできることです。

詳細については、scrapyd APIのドキュメントを参照してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.