스크래피 스파이더에서 사용자 정의 인수를 전달하는 방법


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 : 두 번째 인수 추가

2015 업데이트 : 문구 조정

2016 업데이트 : 최신 기본 클래스를 사용하고 @Birla에게 감사드립니다.

2017 업데이트 : Python3 super 사용

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

2018 업데이트 : @eLRuLL이 지적했듯이 스파이더는 인수에 속성으로 액세스 할 수 있습니다.


3
scrapy 기어 myspider -a 카테고리 = 전자 -a 도메인 = 시스템
스티븐 Almeroth

1
위의 코드는 부분적으로 만 작동합니다. 예를 들어. 을 사용하여 도메인을 정의 self.domain하면 __init__메서드 외부에서 여전히 액세스 할 수 없습니다 . Python에서 정의되지 않은 오류가 발생합니다. BTW, 왜 super전화 를 생략 했습니까? 추신. 저는 CrawlSpider 클래스를 사용하고 있습니다
Birla

2
@FlyingAtom 내가 오해하면 저를 정정하십시오. 그러나 이러한 동시 호출은 각각 거미의 다른 인스턴스가 될 것입니다.
L Lawliet 2015

1
@Birla, 생성자에서 self.domain = domain을 사용하여 클래스 범위 변수를 채 웁니다.
Hassan Raza 2015 년

1
@nealmcb __init__는 스파이더 클래스 의 메서드 입니다. 구현 자체가 스파이더를 덜 견고하게 만드는 것은 아니며 키워드 인수에 대한 기본값을 선언 할 수 있지만 선택 사항이라고 말한대로 대답에 포함되어 있습니다. 작년에 우리가 지적했듯이, getattr당신은 단지 속성으로 인수에 접근 할 수 있습니다. 예를 들어 self.category또는 우리가 대답에서 볼 수 있듯이self.domain
Steven Almeroth 19

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
진실. 파이썬의 어두운면으로 들어가십시오.
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 옵션을 사용하여 crawl 명령을 실행하는 동안 스파이더 인수가 전달됩니다. 예를 들어 스파이더에 대한 인수로 도메인 이름을 전달하려면 다음을 수행합니다.

스크래피 크롤링 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 및 spider 이름을 전달할 수있는 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"

추가 된 이점은 사용자의 URL 및 기타 매개 변수를 수락하고 위의 scrapyd 일정 API를 사용하여 작업을 예약하는 고유 한 UI를 구축 할 수 있다는 것입니다.

자세한 내용은 scrapyd API 문서 를 참조하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.