Scrapy非常基本的例子

您好我的Python上安装了Python Scrapy,我试图按照他们的networking上的第一个例子 。

他们试图运行命令:

scrapy crawl mininova.org -o scraped_data.json -t json 

我不太明白这是什么意思? 看起来像scrapy竟然是一个单独的程序。 我不认为他们有一个叫爬行的命令。 在这个例子中,他们有一段代码,它是类MininovaSpider和TorrentItem的定义。 我不知道这两个类应该去哪里,去同一个文件,这个python文件的名字是什么?

首先,您可能有更好的运气看,而不是“Scrapy一目了然”网页。

本教程暗示Scrapy实际上是一个单独的程序。 运行命令scrapy startproject tutorial将创build一个名为“tutorial”的文件夹,这个文件夹已经为您设置了几个文件 – 项目,pipe道,设置和蜘蛛的python文件:

 tutorial/ scrapy.cfg tutorial/ __init__.py items.py pipelines.py settings.py spiders/ __init__.py ... 

TorrentItem类将放置在items.py ,而MininovaSpider类将放在spiders文件夹中。

项目设置完成后,Scrapy的命令行参数显得相当简单。 他们采取的forms:

 scrapy crawl <website-name> -o <output-file> -t <output-type> 

或者,如果您想在不创build项目目录的情况下运行scrapy,则可以使用runspider命令:

 scrapy runspider my_spider.py 

TL; DR:查看运行scrapy的独立最小示例脚本 。

首先,拥有一个正常的Scrapy项目,一个单独的.cfgsettings.pypipelines.pyitems.pyspiders包等是保持和处理您的networking抓取逻辑的推荐方法。 它提供了一个模块化,关心的分离,使事物组织化,清晰和可testing。

如果您遵循正式的Scrapy教程来创build项目,那么您正在通过一个特殊的scrapy命令行工具来运行networking抓取:

 scrapy crawl myspider 

但是, Scrapy提供了一个 从脚本运行爬行 的API

有几个关键的概念应该提到:

  • Settings类 – 基本上是一个键值“容器”,它是用默认的内置值初始化的
  • Crawler类 – 类似于Scrapy中所涉及的所有不同组件的主类
  • 由于Scrapy是内置于twistedasynchronousnetworking库之上的,所以我们需要将Twisted reactor放入Twisted Reactor (简言之,一个事件循环)中:

反应器是Twisted中的事件循环的核心 – 使用Twisted驱动应用程序的循环。 事件循环是一个编程构造,等待和分派程序中的事件或消息。 它通过调用一些内部或外部的“事件提供者”来工作,这个“事件提供者”一般会阻塞,直到事件到达,然后调用相关的事件处理程序(“调度事件”)。 反应器提供了许多服务的基本接口,包括networking通信,线程和事件调度。

以下是从脚本运行Scrapy的基本和简化过程:

  • 创build一个Settings实例(或使用get_project_settings()来使用现有设置):

     settings = Settings() # or settings = get_project_settings() 
  • 使用传入的settings实例实例化Crawler

     crawler = Crawler(settings) 
  • 实例化一个蜘蛛(这是最终的结果,对吧?):

     spider = MySpider() 
  • configuration信号。 如果你想有一个后处理逻辑, 收集统计数据,或者至less完成抓取,因为这个扭曲的reactor需要手动停止,这是一个重要的步骤。 Scrapy文档build议在spider_closed信号处理程序中停止reactor

请注意,在蜘蛛完成后,您还必须自行closuresTwisted反应堆。 这可以通过将处理程序连接到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) 
  • 使用传入的蜘蛛来configuration和启动搜寻器实例:

     crawler.configure() crawler.crawl(spider) crawler.start() 
  • 可select开始logging :

     log.start() 
  • 启动反应堆 – 这将阻止脚本执行:

     reactor.run() 

以下是一个使用DmozSpider spider的自包含脚本示例,它涉及带有input和输出处理器以及项目pipe道的 项目加载 器 :

 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 

并在pipe道的帮助下观察导出到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可在这里(随意改善):

  • 独立运行scrapy的最小示例脚本

笔记:

如果通过实例化一个Settings()对象来定义settings – 您将获得Scrapy设置的所有默认设置。 但是,如果您想要configuration现有的pipe道,或者configurationDEPTH_LIMIT或调整其他设置,则需要通过settings.set()将其设置在脚本中(如示例所示):

 pipelines = { 'mypackage.pipelines.FilterPipeline': 100, 'mypackage.pipelines.MySQLPipeline': 200 } settings.set('ITEM_PIPELINES', pipelines, priority='cmdline') 

或者,使用预先configuration了所有自定义设置的现有settings.py

 from scrapy.utils.project import get_project_settings settings = get_project_settings() 

其他有关该主题的有用链接:

  • 如何在Python脚本中运行Scrapy
  • 困惑于从Python脚本中运行Scrapy
  • Scrapy从脚本运行蜘蛛