一、開始

首次登陸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 warnings?

stackoverflow.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用戶角色知識:

  1. Read:允許用戶讀取指定資料庫
  2. readWrite:允許用戶讀寫指定資料庫
  3. dbAdmin:允許用戶在指定資料庫中執行管理函數,如索引創建、刪除,查看統計或訪問system.profile
  4. userAdmin:允許用戶向system.users集合寫入,可以找指定資料庫裏創建、刪除和管理用戶
  5. clusterAdmin:只在admin資料庫中可用,賦予用戶所有分片和複製集相關函數的管理許可權。
  6. readAnyDatabase:只在admin資料庫中可用,賦予用戶所有資料庫的讀許可權
  7. readWriteAnyDatabase:只在admin資料庫中可用,賦予用戶所有資料庫的讀寫許可權
  8. userAdminAnyDatabase:只在admin資料庫中可用,賦予用戶所有資料庫的userAdmin許可權
  9. dbAdminAnyDatabase:只在admin資料庫中可用,賦予用戶所有資料庫的dbAdmin許可權。
  10. root:只在admin資料庫中可用。超級賬號,超級許可權

三、Scrapy爬蟲

(1)新建項目

由於我把scrapy爬蟲項目,都放在了scrapy_example文件夾中,所以會先進入相應的文件及,再執行命令

C:Users
enqing.song>cd E:Program Filesscrapy_example

C:Users
enqing.song>e:

E:Program Filesscrapy_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 Filesscrapy_example utorial

You can start your first spider with:
cd tutorial
scrapy genspider example example.com

(2)生成爬蟲文件

E:Program Filesscrapy_example>cd tutorial

E:Program Filesscrapy_example utorial>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 Filesscrapy_example utorial>python -m scrapy crawl quotes

爬蟲結束後,在tutorial資料庫中,會生成一個scrapy的collection(類似mysql裡面表的table概念)

五、結束

至此一個完整的scrapy爬蟲框架,基本完成,並實現了與MongoDB資料庫的鏈接。

推薦閱讀:

相關文章