Python3爬蟲資料入資料庫---把爬取到的資料存到資料庫,帶資料庫去重功能
這是python3實戰入門系列的第三篇文章,要學習這一篇需要了解前兩篇,要不學起來比較費勁
- ofollow,noindex">python3實戰入門python爬蟲篇001---網頁爬蟲,圖片爬蟲,文章爬蟲,Python爬蟲爬取新聞網站新聞
- python3操作資料庫002 藉助pycharm快速連線並操作mysql資料庫
下面來正式開始把我們第一節爬取到的新聞資料儲存到mysql資料中
一,首先我們需要連線資料庫
通過定義一個SQL/">MySQLCommand類來配置資料庫連線引數,並定義一個connectMysql方法連線資料庫
# -*- coding: utf-8 -*- # 作者微信:2501902696 import pymysql # 用來操作資料庫的類 class MySQLCommand(object): # 類的初始化 def __init__(self): self.host = 'localhost' self.port = 3306# 埠號 self.user = 'root'# 使用者名稱 self.password = ""# 密碼 self.db = "home"# 庫 self.table = "home_list"# 表 # 連結資料庫 def connectMysql(self): try: self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user, passwd=self.password, db=self.db, charset='utf8') self.cursor = self.conn.cursor() except: print('connect mysql error.') 複製程式碼
二,連線完資料庫後我們需要插入資料了
插入資料之前我們有兩個問題
- 1,重複的資料如何去重
- 2,新資料的主鍵id應該從哪裡開始 針對上面的兩個問題我貼出一部分程式碼來看解決思路
# 插入資料,插入之前先查詢是否存在,如果存在就不再插入 def insertData(self, my_dict): table = "home_list"# 要操作的表格 # 注意,這裡查詢的sql語句url=' %s '中%s的前後要有空格 sqlExit = "SELECT url FROM home_listWHERE url = ' %s '" % (my_dict['url']) res = self.cursor.execute(sqlExit) if res:# res為查詢到的資料條數如果大於0就代表資料已經存在 print("資料已存在", res) return 0 # 資料不存在才執行下面的插入操作 try: cols = ', '.join(my_dict.keys())#用,分割 values = '"," '.join(my_dict.values()) sql = "INSERT INTO home_list (%s) VALUES (%s)" % (cols, '"' + values + '"') #拼裝後的sql如下 # INSERT INTO home_list (img_path, url, id, title) VALUES ("https://img.huxiucdn.com.jpg"," https://www.huxiu.com90.html"," 12"," ") try: result = self.cursor.execute(sql) insert_id = self.conn.insert_id()# 插入成功後返回的id self.conn.commit() # 判斷是否執行成功 if result: print("插入成功", insert_id) return insert_id + 1 except pymysql.Error as e: # 發生錯誤時回滾 self.conn.rollback() # 主鍵唯一,無法插入 if "key 'PRIMARY'" in e.args[1]: print("資料已存在,未插入資料") else: print("插入資料失敗,原因 %d: %s" % (e.args[0], e.args[1])) except pymysql.Error as e: print("資料庫錯誤,原因%d: %s" % (e.args[0], e.args[1])) 複製程式碼
通過上面程式碼我們來看如何去重
- 我們在每次插入之前需要查詢下資料是否已經存在,如果存在就不在插入,我們的home_list表格的欄位有 id,title,url,img_path。通過分析我們抓取到的資料titlehe和img_path欄位都可能為空,所以這裡我們通過url欄位來去重。知道去重原理以後再去讀上面的程式碼,你應該能容易理解了
三,查詢資料庫中最後一條資料的id值,來確定我們新資料id的開始值
通過下面的getLastId函式來獲取home_list表裡的最後一條資料的id值
# 查詢最後一條資料的id值 def getLastId(self): sql = "SELECT max(id) FROM " + self.table try: self.cursor.execute(sql) row = self.cursor.fetchone()# 獲取查詢到的第一條資料 if row[0]: return row[0]# 返回最後一條資料的id else: return 0# 如果表格為空就返回0 except: print(sql + ' execute failed.') 複製程式碼
下面貼出MySQLCommand資料庫操作類的完整程式碼
# -*- coding: utf-8 -*- # 作者微信:2501902696 import pymysql # 用來操作資料庫的類 class MySQLCommand(object): # 類的初始化 def __init__(self): self.host = 'localhost' self.port = 3306# 埠號 self.user = 'root'# 使用者名稱 self.password = ""# 密碼 self.db = "home"# 庫 self.table = "home_list"# 表 # 連結資料庫 def connectMysql(self): try: self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user, passwd=self.password, db=self.db, charset='utf8') self.cursor = self.conn.cursor() except: print('connect mysql error.') # 插入資料,插入之前先查詢是否存在,如果存在就不再插入 def insertData(self, my_dict): table = "home_list"# 要操作的表格 # 注意,這裡查詢的sql語句url=' %s '中%s的前後要有空格 sqlExit = "SELECT url FROM home_listWHERE url = ' %s '" % (my_dict['url']) res = self.cursor.execute(sqlExit) if res:# res為查詢到的資料條數如果大於0就代表資料已經存在 print("資料已存在", res) return 0 # 資料不存在才執行下面的插入操作 try: cols = ', '.join(my_dict.keys())#用,分割 values = '"," '.join(my_dict.values()) sql = "INSERT INTO home_list (%s) VALUES (%s)" % (cols, '"' + values + '"') #拼裝後的sql如下 # INSERT INTO home_list (img_path, url, id, title) VALUES ("https://img.huxiucdn.com.jpg"," https://www.huxiu.com90.html"," 12"," ") try: result = self.cursor.execute(sql) insert_id = self.conn.insert_id()# 插入成功後返回的id self.conn.commit() # 判斷是否執行成功 if result: print("插入成功", insert_id) return insert_id + 1 except pymysql.Error as e: # 發生錯誤時回滾 self.conn.rollback() # 主鍵唯一,無法插入 if "key 'PRIMARY'" in e.args[1]: print("資料已存在,未插入資料") else: print("插入資料失敗,原因 %d: %s" % (e.args[0], e.args[1])) except pymysql.Error as e: print("資料庫錯誤,原因%d: %s" % (e.args[0], e.args[1])) # 查詢最後一條資料的id值 def getLastId(self): sql = "SELECT max(id) FROM " + self.table try: self.cursor.execute(sql) row = self.cursor.fetchone()# 獲取查詢到的第一條資料 if row[0]: return row[0]# 返回最後一條資料的id else: return 0# 如果表格為空就返回0 except: print(sql + ' execute failed.') def closeMysql(self): self.cursor.close() self.conn.close()# 建立資料庫操作類的例項 複製程式碼
再貼出把爬蟲爬取資料插入到資料庫的程式碼
# -*- coding: utf-8 -*- # 作者微信:2501902696 from bs4 import BeautifulSoup from urllib import request import chardet from db.MySQLCommand import MySQLCommand url = "https://www.huxiu.com" response = request.urlopen(url) html = response.read() charset = chardet.detect(html) html = html.decode(str(charset["encoding"]))# 設定抓取到的html的編碼方式 # 使用剖析器為html.parser soup = BeautifulSoup(html, 'html.parser') # 獲取到每一個class=hot-article-img的a節點 allList = soup.select('.hot-article-img') # 連線資料庫 mysqlCommand = MySQLCommand() mysqlCommand.connectMysql() #這裡每次查詢資料庫中最後一條資料的id,新加的資料每成功插入一條id+1 dataCount = int(mysqlCommand.getLastId()) + 1 for news in allList:# 遍歷列表,獲取有效資訊 aaa = news.select('a') # 只選擇長度大於0的結果 if len(aaa) > 0: # 文章連結 try:# 如果丟擲異常就代表為空 href = url + aaa[0]['href'] except Exception: href = '' # 文章圖片url try: imgUrl = aaa[0].select('img')[0]['src'] except Exception: imgUrl = "" # 新聞標題 try: title = aaa[0]['title'] except Exception: title = "" #把爬取到的每條資料組合成一個字典用於資料庫資料的插入 news_dict = { "id": str(dataCount), "title": title, "url": href, "img_path": imgUrl } try: # 插入資料,如果已經存在就不在重複插入 res = mysqlCommand.insertData(news_dict) if res: dataCount=res except Exception as e: print("插入資料失敗", str(e))#輸出插入失敗的報錯語句 mysqlCommand.closeMysql()# 最後一定要要把資料關閉 dataCount=0 複製程式碼
如果對上面程式碼不是很瞭解可以到我的第一節文章去看下 python3實戰入門python爬蟲篇---網頁爬蟲,圖片爬蟲,文章爬蟲,Python爬蟲爬取新聞網站新聞
到此我們的python3爬蟲+python3資料庫篇就完事了,看下操作效果圖

gif圖片質量不是很好,大家湊合著看吧☺☺☹☎
寫於---Python零基礎實戰入門第四天