博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Scrapy爬虫,数据存入MongoDB
阅读量:4123 次
发布时间:2019-05-25

本文共 5747 字,大约阅读时间需要 19 分钟。

开始

首次登陆MongoDB,由于没有设置用户管理权限,会给出警告,“WARNING: Access control is not enabled for the database”。警告(warning)和错误(error)不一样,你完全可以忽略警告,并不影响你使用MongoDB。

即使你没有创建管理员权限,在没有账号和密码的情况下也可以对数据库进行操作。但是从安全的角度考虑,最好是给要操作的数据库设置账号和密码。

stackoverflow上关于这个问题,有详细的解答,链接如下:

案例主要是参考了 崔庆才 。只是在最后连接MongoDB数据库的时候,由于他的是没有密码的连接,我设置过密码,所以在连接方式上,加入了user,password。其他没有什么区别。

写这篇文章,也是为了理顺自己的思路,顺便动手实践一下。毕竟看别人的代码和自己写代码运行很不一样,即使你完全照着别人的代码写,由于配置环境或者版本问题,都会或多或少出现一些问题。

学习前期都是“依葫芦画瓢”,看别人是怎么做的,别人的思路是怎样。后期积累多了,遇到不同的业务场景,才会加入一些自己的思考。

MongoDB创建用户

创建userAdminAnyDatabase角色,用来管理用户,可以通过这个角色来创建、删除用户。

> use adminswitched to db admin> db.createUser(...   {...     user: "userAdmin",//用户名...     pwd: "123",//密码...     roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]...   }... )Successfully added user: {    "user" : "dba",    "roles" : [        {            "role" : "userAdminAnyDatabase",            "db" : "admin"        }    ]}

role用户角色

Read:允许用户读取指定数据库readWrite:允许用户读写指定数据库dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profileuserAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。root:只在admin数据库中可用。超级账号,超级权限

创建一个数据库 tutorial,并创建一个角色 simple,可以对tutuorial数据库进行读写

> use tutorialswitched to db tutorial> db.createUser({user:"simple",pwd:"test",roles:[{role:"readWrite",db:"tutorial"}]})Successfully added user: {        "user" : "simple",        "roles" : [                {                        "role" : "readWrite",                        "db" : "tutorial"                }        ]}

Scrapy爬虫

新建项目

由于我把scrapy爬虫项目,都放在了scrapy_example文件夹中,所以会先进入相应的文件及,再执行命令

C:\Users\renqing.song>cd E:\Program Files\scrapy_exampleC:\Users\renqing.song>e:E:\Program Files\scrapy_example>python -m scrapy startproject tutorialNew 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\tutorialYou can start your first spider with:    cd tutorial    scrapy genspider example example.com

生成爬虫文件

E:\Program Files\scrapy_example>cd tutorialE:\Program Files\scrapy_example\tutorial>python -m scrapy genspider quotes quotes.toscrapy.com

项目结构

用pycharm打开文件结构如下,__init__.py和scrapy.cfg基本用不上

创建Item

item是保存爬取数据的容器,它的使用方法和字典类似。创建item需要继承scrapy.item类,并且定义类型为scrapy.Field的类属性来定义一个Item。

修改items.py如下

import scrapyclass QuoteItem(scrapy.Item):    # define the fields for your item here like:    # name = scrapy.Field()    text = scrapy.Field()    author = scrapy.Field()    tags = scrapy.Field()

爬虫文件

name:每个项目里面,名字是唯一的,用来区分不同的爬虫项目

allowed_domains:允许爬取的域名,如果初始或者后续请求链接不在这个域名下的,就会被过滤掉。allowed_domains也可以注释掉,不是必须的。

start_urls:包含了spider启动时爬取的url列表,初始请求是由它定义的。

parse:start_urls里面的链接构成的请求完成下载后,返回的response对象,就会传递给parse函数,parse函数负责解析返回的response,提取数据或者进一步生成要处理的请求。

import scrapyfrom tutorial.items import QuoteItemclass 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)

使用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 MongoClientclass 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"  # 主机IPMONGO_PORT = 27017  # 端口号MONGO_DB = "tutorial"  # 库名MONGO_COLL = "scrapy"  # collection名MONGO_USER = "simple" #用户名MONGO_PSW = "test" #用户密码

pipelines.py 文件中,利用 from scrapy.conf import setting可以读取配置文件

import pymongofrom scrapy.conf import settingsclass 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数据库的链接。

你可能感兴趣的文章
Python生态工具
查看>>
Python打造命令行工具
查看>>
iproute2工具详解
查看>>
Linux内核组成部分(一)
查看>>
Linux内核组成部分(二)
查看>>
Linux-4.20.8内核桥收包源码解析(三)----------网卡驱动收包
查看>>
Linux-4.20.8内核桥收包源码解析(一)----------sk_buff(详细)
查看>>
Linux-4.20.8内核桥收包源码解析(二)----------sk_buff的操作
查看>>
Linux-4.20.8内核桥收包源码解析(四)----------netif_receive_skb
查看>>
Linux-4.20.8内核桥收包源码解析(五)----------桥处理流程br_handle_frame
查看>>
Linux-4.20.8内核桥收包源码解析(六)----------决策函数br_handle_frame_finish
查看>>
Linux-4.20.8内核桥收包源码解析(七)----------本地(br_pass_frame_up)or 转发(br_forward)
查看>>
内核中新增驱动代码目录和子目录
查看>>
Maven实现原理
查看>>
Java线程基础
查看>>
线程并发工具类(Fork-Join,CountDownLatch,CyclicBarrier,Semaphore,Exchange)
查看>>
原子操作CAS
查看>>
为什么wait()和notify()需要搭配synchonized关键字使用
查看>>
ThreadLocal及其原理
查看>>
JDK命令行工具的监控
查看>>