一、开始
首次登陆MongoDB,由于没有设置用户管理权限,会给出警告,“WARNING: Access control is not enabled for the database”。警告(warning)和错误(error)不一样,你完全可以忽略警告,并不影响你使用MongoDB。
即使你没有创建管理员权限,在没有账号和密码的情况下也可以对数据库进行操作。但是从安全的角度考虑,最好是给要操作的数据库设置账号和密码。
stackoverflow上关于这个问题,有详细的解答,链接如下:
MongoDB: Server has startup warnings ''Access control is not enabled for the database''stackoverflow.com
MongoDB: Server has startup warningsstackoverflow.com
案例主要是参考了 崔庆才 Scrapy 爬虫框架入门案例详解。只是在最后连接MongoDB数据库的时候,由于他的是没有密码的连接,我设置过密码,所以在连接方式上,加入了user,password。其他没有什么区别。
写这篇文章,也是为了理顺自己的思路,顺便动手实践一下。毕竟看别人的代码和自己写代码运行很不一样,即使你完全照着别人的代码写,由于配置环境或者版本问题,都会或多或少出现一些问题。
学习前期都是“依葫芦画瓢”,看别人是怎么做的,别人的思路是怎样。后期积累多了,遇到不同的业务场景,才会加入一些自己的思考。
二、MongoDB创建用户
创建userAdminAnyDatabase角色,用来管理用户,可以通过这个角色来创建、删除用户。
> use admin
switched to db admin
> db.createUser(
... {
... user: "userAdmin",//用户名
... pwd: "123",//密码
... roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
... }
... )
Successfully added user: {
"user" : "dba",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
创建一个数据库 tutorial,并创建一个角色 simple,可以对tutuorial数据库进行读写
> use tutorial
switched to db tutorial
> db.createUser({user:"simple",pwd:"test",roles:[{role:"readWrite",db:"tutorial"}]})
Successfully added user: {
"user" : "simple",
"roles" : [
{
"role" : "readWrite",
"db" : "tutorial"
}
]
}
补充role用户角色知识:Read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
root:只在admin数据库中可用。超级账号,超级权限
三、Scrapy爬虫
(1)新建项目
由于我把scrapy爬虫项目,都放在了scrapy_example文件夹中,所以会先进入相应的文件及,再执行命令
C:\Users\renqing.song>cd E:\Program Files\scrapy_example
C:\Users\renqing.song>e:
E:\Program Files\scrapy_example>python -m scrapy startproject tutorial
New Scrapy project 'tutorial', using template directory 'E:\\Program Files\\Python 3.6.3\\lib\\site-packages\\scrapy-1.5.0-py3.6.egg\\scrapy\\templates\\project', created in:
E:\Program Files\scrapy_example\tutorial
You can start your first spider with:
cd tutorial
scrapy genspider example example.com
(2)生成爬虫文件
E:\Program Files\scrapy_example>cd tutorial
E:\Program Files\scrapy_example\tutorial>python -m scrapy genspider quotes quotes.toscrapy.com
(3)项目结构
用pycharm打开文件结构如下,__init__.py和scrapy.cfg基本用不上
(4)创建Item
item是保存爬取数据的容器,它的使用方法和字典类似。创建item需要继承scrapy.item类,并且定义类型为scrapy.Field的类属性来定义一个Item。
修改items.py如下
import scrapy
class QuoteItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
text = scrapy.Field()
author = scrapy.Field()
tags = scrapy.Field()
(5)爬虫文件
name:每个项目里面,名字是唯一的,用来区分不同的爬虫项目
allowed_domains:允许爬取的域名,如果初始或者后续请求链接不在这个域名下的,就会被过滤掉。allowed_domains也可以注释掉,不是必须的。
start_urls:包含了spider启动时爬取的url列表,初始请求是由它定义的。
parse:start_urls里面的链接构成的请求完成下载后,返回的response对象,就会传递给parse函数,parse函数负责解析返回的response,提取数据或者进一步生成要处理的请求。
import scrapy
from tutorial.items import QuoteItem
class QuotesSpider(scrapy.Spider):
name = 'quotes'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/']
def parse(self, response):
quotes = response.css('.quote')
for quote in quotes:
item = QuoteItem()
item['text'] = quote.css('.text::text').extract_first()
item['author'] = quote.css('.author::text').extract_first()
item['tags'] = quote.css('.tags .tag::text').extract()
yield item
next = response.css('.pager .next a::attr("href")').extract_first()
url = response.urljoin(next)
yield scrapy.Request(url = url,callback = self.parse)
(6)使用Item Pipeline
如果需要将爬取下来的数据,储存到数据库,就需要使用Item Pipeline来实现。
Item Pipeline意为数据管道,当成Item后,它会自动被送到Item Pipeline进行处理。Item Pipeline主要有以下作用:
1.清理html数据
2.验证爬取数据,检查爬取字段
3.查重并丢弃重复内容
4.将爬取结果储存到数据库
实现Item Pipeline很简单,只需要定义一个类实现process_item方法即可,并且在Setting.py配置文件中启用ITEM_PIPELINES
这个方法主要有两个参数,一个是item,每次spider生成的item都会作为参数传递过来;另外一个是spider,就是spider的实例。
链接MongoDB数据库有两种方法,一种需要在setting.py配置相应的参数,一种是不需要配置,直接初始化的时候,传入相应的值即可。
1.初始化的时候,直接传入相应的值
from pymongo import MongoClient
class MongoPipeline(object):
def __init__(self,databaseIp = '127.0.0.1',databasePort = 27017,user = "simple",password= "test", mongodbName='tutorial'):
client = MongoClient(databaseIp,databasePort)
self.db = client[mongodbName]
self.db.authenticate(user,password)
def process_item(self, item, spider):
postItem = dict(item) # 把item转化成字典形式
self.db.scrapy.insert(postItem) # 向数据库插入一条记录
return item # 会在控制台输出原item数据,可以选择不写
2.在setting.py配置文件中设置参数,调用setting.py文件中的参数值
setting.py配置参数如下,用户名和密码都是在MongoDB创建用户时,建立好的
MONGO_HOST = "127.0.0.1" # 主机IP
MONGO_PORT = 27017 # 端口号
MONGO_DB = "tutorial" # 库名
MONGO_COLL = "scrapy" # collection名
MONGO_USER = "simple" #用户名
MONGO_PSW = "test" #用户密码
pipelines.py 文件中,利用 from scrapy.conf import setting可以读取配置文件
import pymongo
from scrapy.conf import settings
class MongoPipeline(object):
def __init__(self):
# 链接数据库
client = pymongo.MongoClient(host=settings['MONGO_HOST'], port=settings['MONGO_PORT'])
self.db = client[settings['MONGO_DB']] # 获得数据库的句柄
self.coll = self.db[settings['MONGO_COLL']] # 获得collection的句柄
# 数据库登录需要帐号密码的话
self.db.authenticate(settings['MONGO_USER'], settings['MONGO_PSW'])
def process_item(self, item, spider):
postItem = dict(item) # 把item转化成字典形式
self.coll.insert(postItem) # 向数据库插入一条记录
return item # 会在控制台输出原item数据,可以选择不写
四、执行爬虫
E:\Program Files\scrapy_example\tutorial>python -m scrapy crawl quotes
爬虫结束后,在tutorial数据库中,会生成一个scrapy的collection(类似mysql里面表的table概念)
五、结束
至此一个完整的scrapy爬虫框架,基本完成,并实现了与MongoDB数据库的链接。