Cách truyền đối số do người dùng xác định trong scrapy spider


100

Tôi đang cố gắng chuyển một đối số do người dùng xác định tới một trình thu thập dữ liệu. Bất cứ ai có thể đề nghị làm thế nào để làm điều đó?

Tôi đọc về một tham số -aở đâu đó nhưng không biết làm thế nào để sử dụng nó.

Câu trả lời:


188

Đối số Spider được truyền vào crawllệnh bằng cách sử dụng -atùy chọn. Ví dụ:

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

Spider có thể truy cập các đối số dưới dạng thuộc tính:

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

Lấy từ tài liệu Trị liệu: http://doc.scrapy.org/en/latest/topics/spiders.html#spider-arguments

Cập nhật 2013 : Thêm đối số thứ hai

Cập nhật 2015 : Điều chỉnh từ ngữ

Cập nhật 2016 : Sử dụng lớp cơ sở mới hơn và thêm siêu phẩm, cảm ơn @Birla

Cập nhật 2017 : Sử dụng Python3 super

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

Cập nhật năm 2018 : Như @eLRuLL chỉ ra , các trình thu thập dữ liệu có thể truy cập các đối số dưới dạng thuộc tính


3
scrapy bò myspider -a category = điện tử -a domain = hệ thống
Steven Almeroth

1
Đoạn mã trên chỉ hoạt động một phần đối với tôi. Ví dụ. Nếu tôi xác định miền bằng cách sử dụng self.domain, tôi vẫn không thể truy cập miền đó bên ngoài __init__phương thức. Python đưa ra một lỗi không được xác định. BTW, tại sao bạn lại bỏ qua supercuộc gọi? Tái bút. Tôi đang làm việc với lớp CrawlSpider
Birla,

2
@FlyingAtom Vui lòng sửa cho tôi nếu tôi hiểu nhầm, nhưng mỗi lệnh gọi đồng thời này sẽ là các trường hợp nhện khác nhau, phải không?
L Lawliet

1
@Birla, sử dụng miền self.domain = trong hàm tạo để điền biến phạm vi lớp.
Hassan Raza

1
@nealmcb __init__là một phương thức của lớp nhện. Việc triển khai nó không tự nó làm cho spider kém mạnh mẽ hơn và nó được bao gồm trong câu trả lời để cho thấy rằng bạn có thể khai báo giá trị mặc định cho các đối số từ khóa nhưng như bạn đã nói đó là tùy chọn. Như chúng ta đã chỉ ra năm ngoái bạn không cần phải sử dụng getattrbạn có thể lập luận chỉ truy cập như là thuộc tính, ví dụ như self.categoryhay như chúng ta thấy trong câu trả lờiself.domain
Steven Almeroth

31

Các câu trả lời trước đây đều đúng, nhưng bạn không cần phải khai báo hàm tạo ( __init__) mỗi khi bạn muốn viết mã trình thu thập dữ liệu, bạn có thể chỉ định các tham số như trước:

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

và trong mã nhện của bạn, bạn chỉ có thể sử dụng chúng làm đối số nhện:

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

Và nó chỉ hoạt động.


3
Thật. Bước vào mặt tối của python.
Barney

14

Để chuyển các đối số bằng lệnh thu thập thông tin

thu thập thông tin liệu pháp myspider -a category = 'mycategory' -a domain = 'example.com'

Để truyền các đối số để chạy trên scrapyd, hãy thay thế -a bằng -d

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

Spider sẽ nhận các đối số trong phương thức khởi tạo của nó.


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 tất cả các đối số dưới dạng thuộc tính spider và bạn có thể bỏ qua hoàn toàn phương thức init . Hãy cẩn thận khi sử dụng phương thức getattr để lấy các thuộc tính đó để mã của bạn không bị hỏng.


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

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

Succinct, mạnh mẽ và linh hoạt!
nealmcb

8

Đối số Spider được chuyển trong khi chạy lệnh thu thập thông tin bằng cách sử dụng tùy chọn -a. Ví dụ: nếu tôi muốn chuyển một tên miền làm đối số cho trình thu thập thông tin của mình thì tôi sẽ làm điều này-

Scrapy thu thập thông tin myspider -a domain = "http://www.example.com"

Và nhận các đối số trong các hàm tạo của spider:

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

...

nó sẽ hoạt động :)


0

Ngoài ra, chúng ta có thể sử dụng ScrapyD để hiển thị một API nơi chúng ta có thể chuyển start_url và tên spider. ScrapyD có các api để dừng / bắt đầu / trạng thái / liệt kê các nhện.

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

scrapyd-deploysẽ triển khai nhện ở dạng trứng vào daemon và thậm chí nó vẫn duy trì phiên bản của nhện. Trong khi khởi động spider, bạn có thể đề cập đến phiên bản spider sẽ sử dụng.

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"

Lợi thế bổ sung là bạn có thể xây dựng giao diện người dùng của riêng mình để chấp nhận url và các thông số khác từ người dùng và lên lịch tác vụ bằng cách sử dụng API lịch biểu scrapyd ở trên

Tham khảo tài liệu API scrapyd để biết thêm chi tiết

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.