外行學 Python 爬蟲 第九篇 讀取數(shù)據(jù)庫中的數(shù)據(jù)

前面的一至八篇我們一直在研究如何從網(wǎng)站上快速、方便的獲取數(shù)據(jù),并將獲取到的數(shù)據(jù)存儲在數(shù)據(jù)庫中。但是將數(shù)據(jù)存儲在數(shù)據(jù)中并不是我們的目的,獲取和存儲數(shù)據(jù)的目的是為了更好的利用這些數(shù)據(jù),利用這些數(shù)據(jù)的前提首先需要從數(shù)據(jù)庫按一定的格式來讀取數(shù)據(jù),這一篇主要介紹如何實現(xiàn)通過 RESTful API 來獲取數(shù)據(jù)庫中的數(shù)據(jù)。

好吧,廢話有點多,到此介紹吧,接來下進入技術(shù)細節(jié)。

RESTful 是一種軟件架構(gòu)風格、設(shè)計風格,而不是標準,只是提供了一組設(shè)計原則和約束條件。它主要用于客戶端和服務(wù)器交互類的軟件。基于這個風格設(shè)計的軟件可以更簡潔,更有層次,更易于實現(xiàn)緩存等機制。

匹配REST設(shè)計風格的Web API稱為RESTful API。它從三個方面資源進行定義。第一,直觀簡短的資源地址:URI;第二,傳輸?shù)馁Y源:Web服務(wù)接受與返回的互聯(lián)網(wǎng)媒體類型,比如:JSON,XML,YAML等;第三,對資源的操作:Web服務(wù)在該資源上所支持的一系列請求方法(比如:POST,GET,PUT或DELETE)。

實現(xiàn) RESTful API 需要先實現(xiàn)一個 web 服務(wù)器,在本篇中我們通過已有的框架 Flask 來實現(xiàn) web 服務(wù)器,然后在 Flask 的基礎(chǔ)上連通數(shù)據(jù)庫,實現(xiàn) RESTful API 的訪問。

至于 Flask 框架在這里就不做介紹了「其實是我自己也不太懂」,但是你可以在這里 https://dormousehole.readthedocs.io/en/latest/index.html 獲取更多信息。

建立 Flask 基礎(chǔ)服務(wù)

Flask 是一個輕量級的 Web 應(yīng)用框架。通過 Flask 來實現(xiàn)一個 Web 服務(wù)非常簡單,簡單到只需要五行代碼。

from flask import Flask

app = Flask(__name__)

@app.routr('/')
def hello_world():
    return 'Hello World!'

上面使用 Flask 的一個最簡單的示例,我們的示例沒有這么簡單,但是也差不多:)。在這個示例中我們需要創(chuàng)建一個 Flask 的實例、初始化數(shù)據(jù)庫控制和 API 控制框架。代碼如下:

from flask import Flask
import logging

from .module import (
    db,
    api,
)

logger = logging.getLogger(__name__)


def create_app(config=None):
    app = Flask(
        'pycrawler', instance_relative_config=True
    )
    config_app(app, config)
    configure_module(app)
    return app

def config_app(app, config):
    app.config.from_object("pycrawler.configs.default.DefaultConfig")


def configure_module(app):
    # initialization database
    db.init_app(app)

    api.init_app(app)

在程序中通過 app.config.from_object 從配置文件中讀取相關(guān)的配置內(nèi)容,在配置文件中完成數(shù)據(jù)及 flask 的配置。

數(shù)據(jù)庫初始化及數(shù)據(jù)類型的實現(xiàn)

我們使用 Flask 的擴展 Flask-sqlalchemy 來實現(xiàn)數(shù)據(jù)的操作。

Flask-SQLAlchemy 是一個為您的 Flask 應(yīng)用增加 SQLAlchemy 支持的擴展,它致力于簡化在 Flask 中 SQLAlchemy 的使用,提供了有用的默認值和額外的助手來更簡單地完成常見任務(wù)。

flask_sqlalchemy 的使用非常的簡單,僅僅需要簡單的初始化,然后在配置文件加入數(shù)據(jù)庫的 URI 配置即可實現(xiàn)數(shù)據(jù)庫的 CRUD。在這個示例中我們在兩個地方對 flask_sqlalchemy 進行初始化。

首先是初始化 SQLAlchemy 本身,初始化代碼如下:

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData
from flask_restful import Api


metadata = MetaData(
    naming_convention={
        "ix": "ix_%(column_0_label)s",
        "uq": "uq_%(table_name)s_%(column_0_name)s",
        "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
        "pk": "pk_%(table_name)s",
    }
)
db = SQLAlchemy(metadata=metadata)

其次是將 flask 的實例傳入給 flask_sqlchemy。代碼如下:

    # initialization database
    db.init_app(app)

最后在配置文件中增加 SQLAlchemy 的配置選項。

    #Database
    # For SQLite:
    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + basedir + '/' + \
                                  'prcrawler-web.sqlite'

    # This option will be removed as soon as Flask-SQLAlchemy removes it.
    # At the moment it is just used to suppress the super annoying warning
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    # This will print all SQL statements
    SQLALCHEMY_ECHO = False

做完上面的工作以后,數(shù)據(jù)庫已經(jīng)可以正常的工作起來,可以開始著手實現(xiàn)數(shù)據(jù)模型,我們需要連接到前面爬蟲存儲數(shù)據(jù)的數(shù)據(jù)庫,因此需要維持兩個數(shù)據(jù)模型的一致,這里就不再貼出數(shù)據(jù)模型的代碼了。

RESTful API 的實現(xiàn)

在這里使用 flask-restful 擴展來實現(xiàn) RESTful API。flask-restful 的初始同 flask-sqlalchemy 的初始化方法相同。

#創(chuàng)建 api 的實例
api = Api()
#向 api 實例傳入 flask 實例
api.init_app(app)

flask-restful 初始完成后,即可建立 api 的類,以獲取一個元件的信息為例來介紹 api 的建立過程。

from flask_restful import Resource, reqparse
from sqlalchemy import func
from pycrawler.module import db, api
from pycrawler.material.models import Brands, Materials, Price
from flask import jsonify

class CrawlerApi(Resource):
    def get(self, id):
        material = db.session.query(Materials).filter(Materials.id==id).first()
        if material is not None:
            return material.to_json()
        return '', 404

api.add_resource(CrawlerApi, '/api/v0.1/crawler/material/<int:id>')

在 add_resource 中我們設(shè)置 API 的路徑為 /api/v0.1/crawler/material/id 可以通過該 API 來獲取固定 id 的元件的信息。在類 CrawlerApi 中我們實現(xiàn)了一個 get 函數(shù),該函正如其名對應(yīng)了 http 的 get 方法,除了 get 方法我們還能夠以相同的方法來實現(xiàn) post、put、patch、delete 等方法。在 get 函數(shù)中,通過傳入的 id 編號,從數(shù)據(jù)庫中讀出該元件的完整信息,并轉(zhuǎn)換為 json 數(shù)據(jù)返回給客戶端,當 id 不存在是將返回一個 404 錯誤。

在 add_resource 中 <int:id> 將 id 設(shè)置為一個整數(shù),在 get 函數(shù)中傳入的 id 參數(shù)即為一個整數(shù),當然我們也可以設(shè)置為字符串類型。

完成以上代碼后,我們可以通過以下命令來獲取 id 為 100 的元件的信息。

curl http://127.0.0.1:5000/api/v0.1/crawler/material/100

完整的代碼可以通過 api 來訪問所有的元件信息、生產(chǎn)商信息,并可以查看同一個生產(chǎn)商所生產(chǎn)的所有元件。完整的代碼可以在 github 上查看。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容