如何将 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 进行抓取?的主要内容,如果未能解决你的问题,请参考以下文章