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 数据类型
<img src=“https://img-blog.csdnimg.cn/20210129183339102.png” height=1
实战操作
引包
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('<a href="(.*?)">') # 创建正则表达式对象
# 影片图片的链接规则
findImgSrc = re.compile('<img alt=".*src="(.*?)"', re.S) # re.S忽略换行
# 影片片名
findTitle = re.compile('<span class="title">(.*)</span>')
# 影片评分
findRating = re.compile('<span class="rating_num" property="v:average">(.*)</span>')
# 评价人数
# findJudge = re.compile('<span>(\d*)(.*)人评价</span>')
findJudge = re.compile('<span>(\d*)人评价</span>')
# 概况
findInq = re.compile('<span class="inq">(.*)</span>')
# 影片相关内容
findBd = re.compile('<p class="">(.*?)</p>', re.S) # 中间有</br>,因此要忽略换行符
# 爬取网页
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('<br(\s+)?/>(\s+)?', " ", bd) # 去掉</br>
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()
在存储到数据库时确保每个值都存在,即使是空值也要给定空字符串,否则插入数据库可能出错
Affinity ↩︎