Scrapy非常基本的例子

时间:2013-09-16 22:40:40

标签: python web-scraping scrapy

您好我在我的Mac上安装了Python Scrapy,我试图在他们的网站上关注v ery first example

他们试图运行命令:

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

我不太明白这是什么意思?看起来scrapy原来是一个单独的程序。而且我认为他们没有一个名为crawl的命令。在示例中,它们有一段代码,它是MininovaSpider类和TorrentItem的定义。我不知道这两个类应该去哪里,转到同一个文件,这个python文件的名称是什么?

2 个答案:

答案 0 :(得分:52)

TL; DR:请参阅Self-contained minimum example script to run scrapy

首先,建议使用单独的.cfgsettings.pypipelines.pyitems.pyspiders包等正常的Scrapy项目保持和处理您的网络抓取逻辑。它提供了模块化,关注点分离,使事物井井有条,清晰可测。

如果您正在关注official Scrapy tutorial来创建项目,那么您将通过特殊的scrapy命令行工具运行网页抓取:

scrapy crawl myspider

但是,Scrapyrun crawling from a script提供了一个API

应该提到几个关键概念:

  • Settings class - 基本上是一个用default built-in values初始化的键值“容器”
  • Crawler class - 使用Scrapy进行网页抓取所涉及的所有不同组件的主要类别
  • Twisted reactor - 因为Scrapy内置在twisted异步网络库之上 - 要启动一个抓取工具,我们需要将它放在Twisted Reactor内,这很简单单词,事件循环:
  

反应堆是Twisted中事件循环的核心 - 循环使用Twisted驱动应用程序。事件循环是一个等待和的编程结构   在程序中调度事件或消息。它通过调用一些来工作   内部或外部“事件提供者”,通常阻止直到   事件已到达,然后调用相关的事件处理程序   (“发送事件”)。反应器为a提供基本接口   服务数量,包括网络通信,线程和   事件调度。

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

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

    settings = Settings()  # or settings = get_project_settings()
    
  • 实例化Crawler并传入settings个实例:

    crawler = Crawler(settings)
    
  • 实例化一只蜘蛛(这就是它最终的意义,对吗?):

    spider = MySpider()
    
  • 配置信号。如果您希望拥有后处理逻辑collect stats,或者至少要完成爬网,这是一个重要的步骤,因为需要手动停止扭曲的reactor。 Scrapy文档建议停止spider_closed signal处理程序中的reactor

  

请注意,您还必须自己关闭Twisted反应器   蜘蛛完成后。这可以通过连接a来实现   处理signal.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()
    
  • 可选择启动logging

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

    reactor.run()
    

以下是一个使用DmozSpider spider并且item loadersinput and output processorsitem 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()

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

答案 1 :(得分:24)

首先看the tutorial可能会有更好的运气,而不是“一瞥Scrapy”网页。

本教程暗示Scrapy实际上是一个单独的程序。

运行命令scrapy startproject tutorial将创建一个名为tutorial的文件夹,其中包含已为您设置的几个文件。

例如,在我的情况下,模块/包itemspipelinessettingsspiders已添加到根包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