6.Sqlite数据库(数据持久化)

Python3之后默认支持sqlite3数据库,为了提高整个爬虫项目的效率使用轻量级的数据库Sqlite

SQLite 存储类基本数据类型
存储类 描述
NULL 值是一个 NULL 值。
INTEGER 值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。
REAL 值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。
TEXT 值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。
BLOB 值是一个 blob 数据,完全根据它的输入存储。(大数据二进制)

亲和数据类型1请参考菜鸟教程:SQLite 数据类型


实战操作
引包
import sqlite3
1.连接创建数据库
conn = sqlite3.connect("test.db")  # 打开或者创建数据库文件
2.创建表
    c = conn.cursor()  # 游标
    # 三个‘ 保留段落格式
    sql = '''
        create table company
            (id int primary key not null,
            name text not null,
            age int not null,
            address char(50),
            salary real);
    '''
    
    c.execute(sql)  # 执行sql
    conn.commit()  # 提交数据口操作
    conn.close()  # 数据库关闭
3.插入数据
    conn = sqlite3.connect("test.db")  # 打开或者创建数据库文件
    c = conn.cursor()  # 游标
    sql = '''
        insert into company(id, name, age, address, salary)
            values (1, "阿强", 32, "北京", 15000),
            (2, "阿斗", 31, "上海", 10000);
    '''
    c.execute(sql)  # 执行sql
    conn.commit()  # 提交数据库操作
    conn.close()  # 数据库关闭
4.查询数据
    conn = sqlite3.connect("test.db")  # 打开或者创建数据库文件
    c = conn.cursor()  # 游标
    sql = "select id, name, address, salary from company"
    cursor = c.execute(sql)  # 执行sql
    for row in cursor:
        print('id = ', row[0])
        print('name = ', row[1])
        print('address = ', row[2])
        print('salary = ', row[3], '\n')
    conn.close()  # 数据库关闭

建表,表插入数据都是执行sql语句,提交操作,关闭数据库连接,而查询不需要提交操作,查询操作后返回类型是sqlite3.Cursor对象,需要遍历访问结果。太长的sql语句建议使用一对```包裹这样可以保留段落格式从而查询语句不会出错,修改更新数据都是一样的步骤,不做过多演示


任务驱动型开发:将豆瓣Top250电影爬取的数据存储到数据

import re  # 正则表达式,进行文字匹配
# import bs4 #只需要使用bs4中的BeautifulSoup因此可以如下写法:
from bs4 import BeautifulSoup  # 网页解析,获取数据
import xlwt  # 进行excel操作
import sqlite3  # 进行SQLlite数据库操作
import urllib.request, urllib.error  # 指定url,获取网页数据


def main():
    # 爬取的网页
    baseurl = "https://movie.douban.com/top250?start="
    # # 保存的路径
    savepath = ".\\豆瓣电影Top250.xls"  # 使用\\表示层级目录或者在整个字符串前加r“.\豆瓣电影Top250”
    savepath2Db = "movies.db"
    # # 1.爬取网页
    # print(askURL(baseurl))
    datalist = getData(baseurl)
    print(datalist)
    # # 3.保存数据(存储到excel或者DB中)
    saveData(datalist, savepath)
    saveData2Db(datalist, savepath2Db)


# 影片详情链接的规则
findLink = re.compile('')  # 创建正则表达式对象
# 影片图片的链接规则
findImgSrc = re.compile('.*src=(.*)')
# 影片评分
findRating = re.compile('(.*)')
# 评价人数
# findJudge = re.compile('(\d*)(.*)人评价')
findJudge = re.compile('(\d*)人评价')
# 概况
findInq = re.compile('(.*)')
# 影片相关内容
findBd = re.compile('

(.*?)

', re.S) # 中间有
,因此要忽略换行符 # 爬取网页 def getData(baseurl): datalist = [] for i in range(0, 10): # 一页25条电影 url = baseurl + str(i*25) html = askURL(url) # 保存获取到的网页源码 # print(html) # 2.解析数据(逐一) soup = BeautifulSoup(html, "html.parser") # 使用html.parser解析器解析html文档形成树形结构数据 for item in soup.find_all("div", class_="item"): # 查找符合要求的字符串,形成列表 # print(item) data = [] # 保存一部电影的信息 item = str(item) # 影片详情链接 link = re.findall(findLink, item)[0] data.append(link) # 图片 img = re.findall(findImgSrc, item)[0] data.append(img) # 标题 titles = re.findall(findTitle, item) if(len(titles) == 2): ctitle = titles[0] # 中文名 data.append(ctitle) otitle = titles[1].replace("/", "") data.append(otitle) # 外文名 else: data.append(titles[0]) data.append(' ') # 外文名留空 # data.append(title) # 评分 rating = re.findall(findRating, item)[0] data.append(rating) # 评价人数 judgeNum = re.findall(findJudge, item)[0] # print(judgeNum) data.append(judgeNum) # 添加概述 inq = re.findall(findInq, item) if len(inq) == 0: data.append(" ") else: data.append(inq[0].replace("。", "")) # 影片相关内容 bd = re.findall(findBd, item)[0] bd = re.sub('(\s+)?', " ", bd) # 去掉
bd = re.sub('/', " ", bd) # 替换/ data.append(bd.strip()) # 去掉前后的空格 datalist.append(data) # 把处理好的一部电影的信息保存 # for it in datalist: # print(it) return datalist # 得到执行url的网页信息 def askURL(url): # 头部信息 其中用户代理用于伪装浏览器访问网页 head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/87.0.4280.88 Safari/537.36"} req = urllib.request.Request(url, headers=head) html = "" # 获取到的网页源码 try: response = urllib.request.urlopen(req) html = response.read().decode("utf-8") except urllib.error.URLError as e: if hasattr(e, "code"): # has attribute print(e.code) if hasattr(e, "reason"): print(e.reason) return html def saveData(datalist, savepath): book = xlwt.Workbook(encoding="utf-8", style_compression=0) # style_compression:压缩的效果 sheet = book.add_sheet("豆瓣电影top250", cell_overwrite_ok=True) # 单元格内容可覆盖 col = ("电影详情链接", "图片链接", "影片中文名", "影片外文名", "评分", "评价数", "概述", "相关信息") # 元组添加表头 for i in range(8): # 写入表头(列名) sheet.write(0, i, col[i]) for i in range(1, len(datalist)+1): for j in range(len(datalist[i-1])): sheet.write(i, j, datalist[i-1][j]) book.save(savepath) def saveData2Db(datalist, savepath2Db): init_db(savepath2Db) conn = sqlite3.connect(savepath2Db) cur = conn.cursor() for data in datalist: for index in range(len(data)): if index == 4 or index == 5: continue data[index] = '"'+str(data[index])+'"' sql = ''' insert into movie250( info_link, pic_link, cname, ename, score, rated, introduction, info) values(%s) '''%",".join(data) # print(sql) cur.execute(sql) conn.commit() cur.close() conn.close() def init_db(dbpath): sql = ''' create table movie250( id integer primary key autoincrement, info_link text, pic_link text, cname vachar, ename vachar, score numeric, rated numeric, introduction text, info text ) ''' conn = sqlite3.connect(dbpath) # 创建数据连接 cursor = conn.cursor() # 创建游标 cursor.execute(sql) # 执行sql语句 conn.commit() # 提交 # cursor.close() conn.close() # 关闭数据库 if __name__ == '__main__': # init_db("movieTest.db") # 测试数据库初始化 main()

在存储到数据库时确保每个值都存在,即使是空值也要给定空字符串,否则插入数据库可能出错

6.Sqlite数据库(数据持久化)_第1张图片

电影Top250也正常保存到数据库中


  1. Affinity ↩︎

你可能感兴趣的:(爬虫新宠)