嗨!昨天介紹了Spider爬取新聞內容,今天要說明如何透過pipeline將資料存到MySQL資料庫,也提到dotenv如何使用!
dotenv? 一般來說我們會將較敏感的資訊放在.env檔案內,不會直接寫在程式碼中,像是資料庫的位址或帳號密碼等。可以直接到 GitHub - theskumar/python-dotenv 查看範例如何操作,這邊我會直接使用不詳細說明哦。
.env
vim .env
接下來寫入內容到.env檔案(請寫上你自己的不要直接貼上啊~):
MYSQL_DB_NAME = 'MYSQL_DB_NAME'
MYSQL_DB_HOST = 'localhost'
MYSQL_PORY = 3306
MYSQL_USER = 'MYSQL_USER'
MYSQL_PASSWORD = 'MYSQL_PASSWORD'
create table news (
    id int AUTO_INCREMENT, 
    title text,
    content text,
    img text,
    time text, 
    primary key(id)
)
確定好資料庫的設定以及.env設定之後:
settings.py檔案:from dotenv import load_dotenv, find_dotenv
import os
load_dotenv(find_dotenv())
MYSQL_DB_NAME = os.getenv("MYSQL_DB_NAME")
MYSQL_DB_HOST = os.getenv("MYSQL_DB_HOST")
MYSQL_PORY = os.getenv("MYSQL_PORY")
MYSQL_USER = os.getenv("MYSQL_USER")
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD")
print('Connect to db ::', MYSQL_DB_HOST, MYSQL_DB_NAME)

表示有載入.env的內容了!
如果是空值,請確定自己使用的是
python3版本,之前試發現python2版本似乎沒有支援了!
好了之後就可以來寫pipelines.py了,需要將爬到的內容存到資料庫,所以建立一個MySqlPipeline的Class:
class MySqlPipeline(object):
    def open_spider(self, spider):
        pass
    def close_spider(self, spider):
        pass
    def process_item(self, item, spider):
        pass
    def insert_to_mysql(self, item):
        pass
python連接資料庫可以使用pymysql:import pymysql
open_spider(),讓spider被開啟會連接MySQL:def open_spider(self, spider):
        # Database Settings
        db = spider.settings.get('MYSQL_DB_NAME')
        host = spider.settings.get('MYSQL_DB_HOST')
        port = spider.settings.get('MYSQL_PORY')
        user = spider.settings.get('MYSQL_USER')
        password = spider.settings.get('MYSQL_PASSWORD')
        # Database Connecting
        self.connection = pymysql.connect(
            host = host,
            user = user,
            password= password,
            db = db,
            cursorclass= pymysql.cursors.DictCursor
        )
def close_spider(self, spider):
    self.connection.close()
filter_repeat_data的function,若沒有重複則呼叫insert_to_mysql
old_data_from_sql = []
def filter_repeat_data(self, item):
        # Getting Old Data from DB
        with self.connection.cursor() as cursor:
            sql = "SELECT * FROM news"
            cursor.execute(sql)
            for row in cursor:
                self.old_data_from_sql.append(row['title'])
        
        if item['title'] not in self.old_data_from_sql:
            self.insert_to_mysql(item)
insert_to_mysql用來把資料到資料庫:def insert_to_mysql(self, item):
        values = (
            item['title'],
            item['content'],
            item['img'],
            item['time'],
        )
        with self.connection.cursor() as cursor:
            sql = 'INSERT INTO `news` (`title`, `content`, `img`, `time`) VALUES (%s, %s, %s, %s)'
            cursor.execute(sql, values)
            self.connection.commit()
def process_item(self, item, spider):
    self.filter_repeat_data(item)
    return item
這樣就定義完pipeline了,最後我們不能忘記最重要的步驟,到settings.py開啟ITEM_PIPELINES:
ITEM_PIPELINES = {
   'traNews.pipelines.MySqlPipeline': 300,
}
最後,執行程式碼查看資料庫是否有資料新增了:
select * from news

好的,這樣整個流程就完成了,我也將程式碼放到我的 GitHub - plusoneee 
(不過Spider的部分可能會有些許的不同) 今天就到這裡了!明天見!