如何为Scrapy提供要爬取的URL?

36
我想使用Scrapy爬取网页,有没有办法从终端本身传递起始URL?
文档中给出了可以提供蜘蛛名称或URL,但是当我提供URL时,它会抛出错误:
//我的蜘蛛名字是example,但我提供了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在终端中使用我提供的URL来启用我的蜘蛛?

你的爬虫的allowed_domains中是否已添加了example.com? - Sjaak Trekhaak
是的,example.com已添加到allowed_domains。我真正想要的是从命令行中提供start_url。我该怎么做? - G Gill
6个回答

62

我并不确定命令行选项。不过,你可以按照以下方式编写你的爬虫。

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"

这种方法仅适用于一个URL。如果您想提供多个URL,请参见此线程中的我的方法 - pemistahl
2
对于多个URL:self.start_urls = kwargs.pop('start_urls').split(',')在super()之前运行。 - Steven Almeroth

17

比Peter建议的更简单允许多个url参数的方法是将它们作为一个字符串给出,用逗号隔开,像这样:

-a start_urls="http://example1.com,http://example2.com"
在 spider 中,您只需将字符串按 ',' 分割,即可获取一个 URL 数组:
self.start_urls = kwargs.get('start_urls').split(',')

8
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)

问题是哪种做法更好:kwargs.pop('start_urls') 还是 kwargs.get('start_urls') - derwana

7

2
不幸的是,scrapy parse 似乎没有像 scrapy crawl 那样将结果保存到文件中(以各种格式)的选项。 - dan3
如果您只是想调试爬虫失败的特定URL,这是一个简单的选项。 - jeffjv
1
无法轻松保存/导出文件。否则这将是完美的。 - Citricguy

4

这是对Sjaak Trekhaak在此主题中提供方法的扩展。目前该方法仅在您提供一个确切的URL时有效。例如,如果您想要提供多个URL,如下所示:

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

如果使用当前稳定版本0.14.4的Scrapy,则会出现以下异常并终止:

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中,并在循环或其他方式中生成命令行参数是有意义的。
希望这能有所帮助。 :)

如果我这样调用Scrapy 0.24.4: “scrapy crawl MySpider -a start_urls=http://example.com/ -o - -t json”, 一切都能正常工作。 最初我把选项放在-o和-之间,结果得到了相同的错误。 - mmv-ru

-1

你也可以尝试这个:

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

它将在浏览器中打开请求的URL窗口。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接