首页 > 代码库 > scrapy+mongodb

scrapy+mongodb

  我们都知道scrapy适合爬取大量的网站信息,爬取到的信息储存到数据库显然需要更高的效率,scrapy配合mongodb是非常合适的,这里记录一下如何在scrapy中配置mongodb。

文件结构

$ scrapy startproject myscrapy

当我们创建一个scrapy工程的时候,scrapy会自动给我们创建目录结构,像下面这样:

├── scrapy.cfg
└── myscrapy
    ├── __init__.py
    ├── items.py
    ├── pipelines.py
    ├── settings.py
    └── spiders
        └── __init__.py

 

提取数据

items.py文件用于定义存储“容器”,用来存储将要抓取的数据。

MyscrapyItem()类继承自Item (文档),主要包含一些Scrapy已经为我们创建好的预定义对象:

import scrapy


class MyscrapyItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass

添加一些想要收集的项。用户想要每条问题的标题和URL。那么,照这样更新items.py:

from scrapy.item import Item, Field
 
class MyscrapyItem(Item):
    title = Field()
url = Field()

 

创建蜘蛛

$ scrapy genspider myspider baidu.com

这样,scrapy会为我们在spiders目录下生成一个myspider.py的文件

import scrapy
from myscrapy.items import MyscrapyItem # 导入我们的item类 class MyspiderSpider(scrapy.Spider): name = ‘myspider‘ allowed_domains = [‘baidu.com‘] start_urls = [‘http://baidu.com/‘] def parse(self, response):
item = MyscrapyItem() # 实例化item类 item[‘title‘] = response.title # 此行为伪代码
item[‘url] = response.url
yield item # 这句会将item数据交给pipelines处理

最初一些变量的含义很容易理解(文档):

  • 定义蜘蛛的名字。
  • allowed_domains 包含构成许可域的基础URL,供蜘蛛去爬。
  • start_urls 是一个URL列表,蜘蛛从这里开始爬。蜘蛛从start_urls中的URL下载数据,所有后续的URL将从这些数据中获取。

抓取数据的伪代码已经写好了,接下来要将拿到的数据存储到数据库中

在MongoDB中存储数据

每当有一项返回,我们想验证数据,然后添加进一个Mongo集合。

第一步是创建一个我们计划用来保存所有抓取数据的数据库。打开settings.py,指定管道然后加入数据库设置:

ITEM_PIPELINES = {
   ‘myscrapy.pipelines.MyscrapyPipeline‘: 300,
}
MONGODB_SERVER = "localhost"
MONGODB_PORT = 27017
MONGODB_DB = "crawl"
MONGODB_COLLECTION = "item" 

管道管理

我们建立了爬虫去抓取数据,而且已经设置了数据库配置。现在要在pipelines.py中通过一个管道连接两个部分。

连接数据库

首先,让我们定义一个函数去连接数据库:

import pymongo

from scrapy.conf import settings


class MyscrapyPipeline(object):
    def __init__(self):
        connection = pymongo.Connection(
            settings[‘MONGODB_SERVER‘],
            settings[‘MONGODB_PORT‘]
        )
        db = connection[settings[‘MONGODB_DB‘]]
        self.collection = db[settings[‘MONGODB_COLLECTION‘]]
        
    def process_item(self, item, spider):
        return item

这里,我们创建一个类,MongoDBPipeline(),我们有一个构造函数初始化类,它定义Mongo的设置然后连接数据库。

处理数据

下一步,我们需要定义一个函数去处理被解析的数据:

import pymongo

from scrapy.conf import settings
from scrapy.exceptions import DropItem
from scrapy import log


class MyscrapyPipeline(object):
    def __init__(self):
        connection = pymongo.Connection(
            settings[‘MONGODB_SERVER‘],
            settings[‘MONGODB_PORT‘]
        )
        db = connection[settings[‘MONGODB_DB‘]]
        self.collection = db[settings[‘MONGODB_COLLECTION‘]]

    def process_item(self, item, spider):
        valid = True
        for data in item:
            if not data:
                valid = False
                raise DropItem("Missing {0}!".format(data))
        if valid:
            self.collection.insert(dict(item))  # 将item解包后存入mongodb中
            log.msg("Question added to MongoDB database!",
                    level=log.DEBUG, spider=spider)
        return item

现在可以运行我们的scrapy了!

在总的myscrapy目录下运行下面命令:

$ $ scrapy crawl myscrapy

如果日志打印成功,可以去mongodb里找我们对应的数据库和集合,去查看数据。

scrapy+mongodb