如何将 URL 提供给 scrapy 进行抓取?

Posted

技术标签:

【中文标题】如何将 URL 提供给 scrapy 进行抓取?【英文标题】:How to give URL to scrapy for crawling? 【发布时间】:2012-03-29 16:21:29 【问题描述】:

我想用scrapy来抓取网页。有没有办法从终端本身传递起始 URL?

documentation 中给出了蜘蛛的名称或 URL 都可以给出,但是当我给出 url 时它会抛出错误:

//我的蜘蛛名称是示例,但我给出的是 url 而不是我的蜘蛛名称(如果我给出蜘蛛名称,它可以正常工作)。

scrapy crawl example.com

错误:

文件 "/usr/local/lib/python2.7/dist-packages/Scrapy-0.14.1-py2.7.egg/scrapy/spidermanager.py", 第 43 行,在创建中 raise KeyError("Spider not found: %s" % spider_name) KeyError: 'Spider not found: example.com'

我怎样才能让scrapy在终端给出的url上使用我的蜘蛛??

【问题讨论】:

是否将 example.com 添加到您的蜘蛛的 allowed_domains 中? 是的 example.com 已添加到 allowed_domains。我真正想要的是从命令行给出 start_url 。我该怎么做? 【参考方案1】:

我不太确定命令行选项。然而,你可以这样写你的蜘蛛。

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"

【讨论】:

非常感谢,这正是我想要的。它对我来说很好:) 这种方法只适用于一个网址。如果您想提供多个网址,请参阅本帖中的my approach。 对于多个 URL:self.start_urls = kwargs.pop('start_urls').split(','),它在 super()之前运行。【参考方案2】:

使用scrapy parse 命令。你可以用你的蜘蛛解析一个网址。 url 是从命令传递过来的。

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

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

【讨论】:

不幸的是,scrapy parse 似乎没有像 scrapy crawl 那样将结果保存到文件(各种格式)的选项 如果你只是想调试为什么你的蜘蛛在某个特定的 url 上失败了,这是一个简单的选择。 无法轻松保存/导出到文件。否则这将是完美的。【参考方案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_url0'.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 和 - 之间并得到与 You 错误相同的结果。【参考方案4】:

允许多个 url 参数比 Peter 建议的更简单的方法是将它们作为字符串提供,url 用逗号分隔,如下所示:

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

在蜘蛛中,您只需将字符串拆分为 ',' 并获得一个 url 数组:

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

【讨论】:

【参考方案5】:

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')?【参考方案6】:

你也可以试试这个:

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

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

【讨论】:

以上是关于如何将 URL 提供给 scrapy 进行抓取?的主要内容,如果未能解决你的问题,请参考以下文章

Scrapy+Scrapy-redis+Scrapyd+Gerapy 分布式爬虫框架整合

scrapy自动抓取蛋壳公寓最新房源信息并存入sql数据库

Scrapy简介

scrapy框架全栈/深度抓取

scrapy抓取豆瓣电影相关数据

使用 Scrapy 传递请求