嗨我在我的Mac上安装了Python Scrapy,我试图在他们的网站上关注very first example。
他们试图运行命令:
scrapy crawl mininova.org -o scraped_data.json -t json
我不太明白这是什么意思?看起来scrapy原来是一个单独的程序。而且我认为他们没有一个名为crawl的命令。在示例中,它们有一段代码,它是MininovaSpider类和TorrentItem的定义。我不知道这两个类应该去哪里,转到同一个文件,这个python文件的名称是什么?
你可能有更好的运气首先通过the tutorial,而不是“一瞥Scrapy”网页。
该教程暗示Scrapy实际上是一个单独的程序。
运行命令scrapy startproject tutorial
将创建一个名为tutorial
的文件夹,其中包含已为您设置的几个文件。
例如,在我的例子中,模块/包items
,pipelines
,settings
和spiders
已添加到根包tutorial
中。
tutorial/
scrapy.cfg
tutorial/
__init__.py
items.py
pipelines.py
settings.py
spiders/
__init__.py
...
TorrentItem
类将被放置在items.py
内,而MininovaSpider
类将进入spiders
文件夹。
设置项目后,Scrapy的命令行参数看起来相当简单。他们采取以下形式:
scrapy crawl <website-name> -o <output-file> -t <output-type>
或者,如果要在没有创建项目目录的情况下运行scrapy,可以使用runspider命令:
scrapy runspider my_spider.py
TL; DR:见Self-contained minimum example script to run scrapy。
首先,建立一个普通的Scrapy项目,包括单独的.cfg
,settings.py
,pipelines.py
,items.py
,spiders
包等,这是一种保持和处理网络抓取逻辑的推荐方法。它提供了模块化,关注点分离,使事物井井有条,清晰可测。
如果您按照official Scrapy tutorial创建项目,则通过特殊的scrapy
命令行工具运行web-scraping:
scrapy crawl myspider
但是,Scrapy
还为run crawling from a script提供了一个API。
应该提到几个关键概念:
Settings
class - 基本上是一个键值“容器”,用default built-in values初始化Crawler
class - 使用Scrapy进行网络抓取所涉及的所有不同组件的主要类别reactor
- 因为Scrapy内置在twisted
异步网络库之上 - 要启动一个爬虫,我们需要把它放在Twisted Reactor中,简单来说就是一个事件循环:反应堆是Twisted中事件循环的核心 - 循环使用Twisted驱动应用程序。事件循环是一种编程构造,它等待和分派程序中的事件或消息。它通过调用一些内部或外部“事件提供程序”来工作,它通常会阻塞直到事件到达,然后调用相关的事件处理程序(“调度事件”)。该反应器为许多服务提供基本接口,包括网络通信,线程和事件分派。
以下是从脚本运行Scrapy的基本简化过程:
Settings
实例(或使用get_project_settings()
来使用现有设置):
settings = Settings() # or settings = get_project_settings()
Crawler
实例实例化settings
:
crawler = Crawler(settings)
spider = MySpider()
reactor
。 Scrapy文档建议在reactor
处理程序中停止spider_closed
signal:请注意,在蜘蛛完成后您还必须自己关闭Twisted reactor。这可以通过将处理程序连接到signals.spider_closed信号来实现。
def callback(spider, reason):
stats = spider.crawler.stats.get_stats()
# stats here is a dictionary of crawling stats that you usually see on the console
# here we need to stop the reactor
reactor.stop()
crawler.signals.connect(callback, signal=signals.spider_closed)
crawler.configure()
crawler.crawl(spider)
crawler.start()
log.start()
reactor.run()
这是一个使用DmozSpider
spider的示例自包含脚本,涉及item loaders与input and output processors和item pipelines:
import json
from scrapy.crawler import Crawler
from scrapy.contrib.loader import ItemLoader
from scrapy.contrib.loader.processor import Join, MapCompose, TakeFirst
from scrapy import log, signals, Spider, Item, Field
from scrapy.settings import Settings
from twisted.internet import reactor
# define an item class
class DmozItem(Item):
title = Field()
link = Field()
desc = Field()
# define an item loader with input and output processors
class DmozItemLoader(ItemLoader):
default_input_processor = MapCompose(unicode.strip)
default_output_processor = TakeFirst()
desc_out = Join()
# define a pipeline
class JsonWriterPipeline(object):
def __init__(self):
self.file = open('items.jl', 'wb')
def process_item(self, item, spider):
line = json.dumps(dict(item)) + "\n"
self.file.write(line)
return item
# define a spider
class DmozSpider(Spider):
name = "dmoz"
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
]
def parse(self, response):
for sel in response.xpath('//ul/li'):
loader = DmozItemLoader(DmozItem(), selector=sel, response=response)
loader.add_xpath('title', 'a/text()')
loader.add_xpath('link', 'a/@href')
loader.add_xpath('desc', 'text()')
yield loader.load_item()
# callback fired when the spider is closed
def callback(spider, reason):
stats = spider.crawler.stats.get_stats() # collect/log stats?
# stop the reactor
reactor.stop()
# instantiate settings and provide a custom configuration
settings = Settings()
settings.set('ITEM_PIPELINES', {
'__main__.JsonWriterPipeline': 100
})
# instantiate a crawler passing in settings
crawler = Crawler(settings)
# instantiate a spider
spider = DmozSpider()
# configure signals
crawler.signals.connect(callback, signal=signals.spider_closed)
# configure and start the crawler
crawler.configure()
crawler.crawl(spider)
crawler.start()
# start logging
log.start()
# start the reactor (blocks execution)
reactor.run()
以通常的方式运行它:
python runner.py
并在管道的帮助下观察导出到items.jl
的物品:
{"desc": "", "link": "/", "title": "Top"}
{"link": "/Computers/", "title": "Computers"}
{"link": "/Computers/Programming/", "title": "Programming"}
{"link": "/Computers/Programming/Languages/", "title": "Languages"}
{"link": "/Computers/Programming/Languages/Python/", "title": "Python"}
...
这里有Gist(随意改进):
笔记:
如果通过实例化settings
对象来定义Settings()
- 您将获得所有默认的Scrapy设置。但是,如果您想要,例如,配置现有管道,或配置DEPTH_LIMIT
或调整任何其他设置,您需要通过settings.set()
在脚本中设置它(如示例中所示):
pipelines = {
'mypackage.pipelines.FilterPipeline': 100,
'mypackage.pipelines.MySQLPipeline': 200
}
settings.set('ITEM_PIPELINES', pipelines, priority='cmdline')
或者,使用现有的settings.py
预先配置的所有自定义设置:
from scrapy.utils.project import get_project_settings
settings = get_project_settings()
有关该主题的其他有用链接: