6Python3實戰入門資料庫篇003---把爬取到的資料存到資料庫,帶資料庫去重功能
阿新 • • 發佈:2018-12-03
這是python3實戰入門系列的第三篇文章,要學習這一篇需要了解前兩篇,要不學起來比較費勁
下面來正式開始把我們第一節爬取到的新聞資料儲存到mysql資料中
一,首頁我們需要連線資料庫
通過定義一個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_list WHERE 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_list WHERE 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.gif
作者:java小石頭
連結:https://www.jianshu.com/p/5ba719a7d8cb
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。