2012-03-13 109 views
21

我想使用scrapy來抓取網頁。有沒有辦法從終端本身傳遞起始URL?如何爲scrapy提供抓取網址?

它在documentation給出了蜘蛛或URL的任何名字可以給,但是當我給出的網址,它拋出一個錯誤:

我的蜘蛛

//名稱爲例子,但我我給的網址,而不是我的蜘蛛名(它工作正常,如果我給蜘蛛的名字)。

scrapy crawl example.com

錯誤:

File "/usr/local/lib/python2.7/dist-packages/Scrapy-0.14.1-py2.7.egg/scrapy/spidermanager.py", line 43, in create raise KeyError("Spider not found: %s" % spider_name) KeyError: 'Spider not found: example.com'

我怎樣才能讓scrapy使用我的蜘蛛在終端給出的網址?

+0

example.com是否被添加到您的蜘蛛allowed_domains? – 2012-03-13 10:12:41

+0

yes example.com已添加到allowed_domains。我真正想要的是從命令行給start_url。我該怎麼做? – 2012-03-13 10:38:10

回答

43

我不太確定命令行選項。但是,你可以像這樣寫你的蜘蛛。

class MySpider(BaseSpider): 

    name = 'my_spider'  

    def __init__(self, *args, **kwargs): 
     super(MySpider, self).__init__(*args, **kwargs) 

     self.start_urls = [kwargs.get('start_url')] 

並啓動它想: scrapy crawl my_spider -a start_url="http://some_url"

+0

非常感謝你,這正是我一直在尋找的。它適用於我:) – 2012-03-13 11:26:07

+0

這種方法只適用於一個網址。如果您想提供多個網址,請參閱本主題中的[我的方法](http://stackoverflow.com/a/12749782/1125413)。 – pemistahl 2012-10-05 16:11:23

+1

對於多個URL:'self.start_urls = kwargs.pop('start_urls')。split(',')'在* super()之前運行*。 – 2015-02-16 18:20:27

3

使用scrapy解析命令。你可以用你的蜘蛛解析一個網址。網址是從命令傳遞的。

$ scrapy parse http://www.example.com/ --spider=spider-name 

http://doc.scrapy.org/en/latest/topics/commands.html#parse

+0

不幸的是,scrapy parse似乎沒有將結果保存到文件(以各種格式)的選項,比如scrapy抓取 – dan3 2013-02-24 07:28:16

+0

如果您正在尋找只調試爲什麼特定的網址您的蜘蛛在此失敗是一個簡單的選擇。 – jeffjv 2016-04-20 00:10:29

+0

無法輕鬆保存/導出到文件。否則,這將是完美的。 – Citricguy 2017-05-22 12:34:26

3

這是一個擴展到the approach given by Sjaak Trekhaak在這個線程。到目前爲止,這種方法只有在您提供一個url時纔有效。例如,如果要提供多個URL這樣的,例如:

-a start_url=http://url1.com,http://url2.com 

然後Scrapy(我使用的是當前穩定版本0.14.4)將與以下異常終止:

error: running 'scrapy crawl' with more than one spider is no longer supported 

但是,您可以通過爲每個啓動url選擇一個不同的變量以及一個保存傳遞的url數量的參數來繞過這個問題。事情是這樣的:

-a start_url1=http://url1.com 
-a start_url2=http://url2.com 
-a urls_num=2 

然後,您可以做你的蜘蛛如下:

class MySpider(BaseSpider): 

    name = 'my_spider'  

    def __init__(self, *args, **kwargs): 
     super(MySpider, self).__init__(*args, **kwargs) 

     urls_num = int(kwargs.get('urls_num')) 

     start_urls = [] 
     for i in xrange(1, urls_num): 
      start_urls.append(kwargs.get('start_url{0}'.format(i))) 

     self.start_urls = start_urls 

這是一個有點醜陋的黑客攻擊,但它的工作原理。當然,明確寫下每個url的所有命令行參數非常繁瑣。因此,將scrapy crawl命令包裝在Python subprocess中並在循環或其他東西中生成命令行參數是有意義的。

希望它有幫助。:)

+0

如果我打電話給scrapy 0.24.4就像這樣: 'scrapy抓取MySpider -a start_urls = http://example.com/ -o - -t json' 一切正常。 最初我把選項放在-o和 - 之間,並得到和你一樣的錯誤。 – 2015-11-02 22:11:59

10

一個更簡單的方法來允許多個URL的參數比彼得建議是讓他們與用逗號分隔的URL字符串,像這樣:

-a start_urls="http://example1.com,http://example2.com" 

在蜘蛛你會然後簡單地拆分的字符串「」並獲得網址數組:

self.start_urls = kwargs.get('start_urls').split(',') 
3

Sjaak Trekhaak看法是正確的,這裏是如何讓倍數:

class MySpider(scrapy.Spider): 
    """ 
    This spider will try to crawl whatever is passed in `start_urls` which 
    should be a comma-separated string of fully qualified URIs. 

    Example: start_urls=http://localhost,http://example.com 
    """ 
    def __init__(self, name=None, **kwargs): 
     if 'start_urls' in kwargs: 
      self.start_urls = kwargs.pop('start_urls').split(',') 
     super(Spider, self).__init__(name, **kwargs) 
0

你也可以試試這個:

>>> scrapy view http://www.sitename.com 

它將請求的URL的瀏覽器中打開一個窗口。