天天看点

python爬虫scrapy连接mongodb_Scrapy爬虫,数据存入MongoDB

一、开始

首次登陆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

python爬虫scrapy连接mongodb_Scrapy爬虫,数据存入MongoDB

MongoDB: Server has startup warnings​stackoverflow.com

python爬虫scrapy连接mongodb_Scrapy爬虫,数据存入MongoDB

案例主要是参考了 崔庆才 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数据库的链接。