วิธีการส่งผ่านอาร์กิวเมนต์ที่ผู้ใช้กำหนดในแมงมุม scrapy


102

ฉันกำลังพยายามส่งต่ออาร์กิวเมนต์ที่ผู้ใช้กำหนดให้กับแมงมุมของ scrapy ใครสามารถแนะนำวิธีการทำ?

ฉันอ่านเกี่ยวกับพารามิเตอร์-aที่ไหนสักแห่ง แต่ไม่รู้ว่าจะใช้อย่างไร

คำตอบ:


193

อาร์กิวเมนต์ Spider ถูกส่งผ่านใน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 crawl myspider -a category = electronics -a domain = system
Steven Almeroth

1
โค้ดด้านบนใช้งานได้เพียงบางส่วนสำหรับฉัน สำหรับเช่น หากฉันกำหนดโดเมนโดยใช้self.domainฉันยังไม่สามารถเข้าถึงได้นอก__init__วิธีการ Python แสดงข้อผิดพลาดที่ไม่ได้กำหนดไว้ BTW ทำไมคุณถึงsuperไม่รับสาย? ปล. ฉันกำลังทำงานกับคลาส CrawlSpider
Birla

2
@FlyingAtom โปรดแก้ไขฉันหากฉันเข้าใจผิด แต่การโทรพร้อมกันแต่ละครั้งจะเป็นกรณีที่แตกต่างกันของแมงมุมใช่ไหม
L Lawliet

1
@Birla ใช้ self.domain = domain ในตัวสร้างเพื่อเติมข้อมูลตัวแปรขอบเขตคลาส
Hassan Raza

1
@nealmcb __init__เป็นวิธีการหนึ่งของคลาสแมงมุม การนำไปใช้งานไม่ได้ทำให้แมงมุมมีความแข็งแกร่งน้อยลงและรวมอยู่ในคำตอบเพื่อแสดงว่าคุณสามารถประกาศค่าเริ่มต้นสำหรับอาร์กิวเมนต์คำหลักได้ แต่อย่างที่คุณบอกว่าเป็นทางเลือก ดังที่เราได้ชี้ให้เห็นเมื่อปีที่แล้วคุณไม่จำเป็นต้องใช้getattrคุณก็สามารถเข้าถึงอาร์กิวเมนต์เป็นแอตทริบิวต์เช่นself.categoryหรือที่เราเห็นในคำตอบself.domain
Steven Almeroth

34

คำตอบก่อนหน้านี้ถูกต้อง แต่คุณไม่จำเป็นต้องประกาศตัวสร้าง ( __init__) ทุกครั้งที่คุณต้องการโค้ดสไปเดอร์ของ scrapy คุณสามารถระบุพารามิเตอร์ได้เหมือนเดิม:

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 Szabolcs

14

เพื่อส่งผ่านอาร์กิวเมนต์ด้วยคำสั่ง crawl

scrapy รวบรวมข้อมูล 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 ทำให้อาร์กิวเมนต์ทั้งหมดเป็นคุณลักษณะของแมงมุมและคุณสามารถข้ามวิธีการเริ่มต้นได้ทั้งหมด ระวังใช้เมธอด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

อาร์กิวเมนต์ Spider ถูกส่งผ่านขณะรันคำสั่ง crawl โดยใช้อ็อพชัน -a ตัวอย่างเช่นถ้าฉันต้องการส่งชื่อโดเมนเป็นอาร์กิวเมนต์ไปยังแมงมุมของฉันฉันจะทำสิ่งนี้ -

scrapy รวบรวมข้อมูล 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

หรือเราสามารถใช้ScrapyDซึ่งแสดง API ที่เราสามารถส่งชื่อ start_url และ spider 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 และพารามิเตอร์อื่น ๆ จากผู้ใช้และกำหนดเวลางานโดยใช้ scrapyd schedule API ด้านบน

อ้างอิงเอกสาร scrapyd APIสำหรับรายละเอียดเพิ่มเติม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.