我爱编程

Scrapy 如何配置 MongoDB

2018-05-06  本文已影响46人  Paycation

配置环境
MacOS, Python3.6, scrapy 1.5

安装 MongoDB

安装 mongodb

brew install mongodb

启动服务,否则会报 connection failed。也可以通过 mongod 启动。

brew services start mongodb

安装 pymongo

pip install pymongo

Scrapy 配置

spiders/your_spider.py

from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst, MapCompose
from your.items import YourItem

class YourItemLoader(ItemLoader):
    def get_id(value):
        return value.strip()
    default_item_class = YourItem
    default_output_processor = TakeFirst()
    id_in = MapCompose(get_id)

class YourSpider(scrapy.Spider):
     ...
    def parse(self, response):
        for block in response.xpath('//ul[@id="houselist-mod-new"]'):
            l = YourItemLoader(selector=block) # 
            l.add_xpath('title', 'div[@class="house-details"]/a/text()')
            l.add_xpath('id', 'div[@class="house-details"]/a/text()')
            return load_item() 

在 your_spider.py 下的 YourSpider 类下定义即可。
其中 MapCompose 的作用是用一个特定的函数预处理一个字段。例如用 get_id 这个自定义函数处理 id 这个字段,这样就不需要把数据的清理放到 parse 里,造成代码过于臃肿。
default_output_processor = TakeFirst() 的意义在于:让返回的 item 的字段不再是列表。如果不加这行,返回的字段都是 list 对象。

settings.py

ITEM_PIPELINES = {
   'your.pipelines.MongoDBPipeline': 300,
}
MONGO_URI = 'mongodb://127.0.0.1:27017'
MONGO_DATABASE = 'fangdb'  # 可以自定义

pipelines.py

import pymongo

class MongoDBPipeline(object):
    collection_name= 'youritems'  # 数据库中 collection 的命名
    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db
    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            mongo_uri=crawler.settings.get('MONGO_URI'),
            mongo_db=crawler.settings.get('MONGO_DATABASE') 
        )
    def open_spider(self,spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]
    def close_spider(self, spider):
        self.client.close()
    def process_item(self, item, spider):
        self.db[self.collection_name].insert(dict(item))
        return item

这部分的代码来自官方文档
至此,已经配置完毕。

查看数据库

通过命令行查看:

mongo # 默认连接到 127.0.0.1:27017,连接远程数据库需要带其他参数
show dbs # 显示所有数据库
db # 查看当前的数据库,一般是返回 test
use fangdb # 切换到该数据库,之后 db 就用来代指这个数据库了
db.fangitems.find().pretty() # 打印数据库的内容
# 效果大致如下:
{
    "_id" : ObjectId("5aef1930140c1f5a0f2aa642"),
    "title" : "虽说是以前的装修,但是保护的很好,中间楼层,小区环境不错",
    "link" : "https://mianyang.anjuke.com/prop/view/A1216411683?from=filter&spread=filtersearch&invalid=1&position=1&kwtype=filter&now_time=1525618992",
    "id" : "A1216411683",
    "room" : "2室2厅",
    "area" : "88m²",
    "floor" : "共4层",
    "year" : "1990年建造",
    "addr" : "花园小区 | 涪城-涪城-临园大道与金菊街交汇处",
    "total" : "62万",
    "unit" : "7045元/m²"
}
{
    "_id" : ObjectId("5aef1930140c1f5a0f2aa643"),
    "title" : "想投 资的赶紧来了 跃进路上 繁华地段 价格便宜 税费低!!",
    "link" : "https://mianyang.anjuke.com/prop/view/A1212834910?from=filter&spread=filtersearch_t&position=2&kwtype=filter&now_time=1525618992",
    "id" : "A1212834910",
    "room" : "2室2厅",
    "area" : "66m²",
    "floor" : "低层(共7层)",
    "year" : "2000年建造",
    "addr" : "高水小区 | 涪城-涪城-涪城区跃进路北段87号",
    "total" : "42万",
    "unit" : "6363元/m²"
}
....

也可以使用图形化工具查看。
下载地址 https://robomongo.org
界面大概如下:

image.png
上一篇 下一篇

猜你喜欢

热点阅读