Python学习笔记7-SQLite模块及应用

前面使用xlwt模块爬取数据到excel表中,这次用sqlite3模块爬取数据到数据库中。

SQLite基础

SQLite是python3默认支持的数据库,它是一个轻型数据库,一个db文件就是一个数据库

1.连接数据库

1
con=sqlite3.connect("test.db") #打开或创建(文件不存在时)数据库文件。相对路径,也可以用绝对路径。Pycharm软件右侧Database可以操作数据库

2.创建数据表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
con=sqlite3.connect("test.db")
print("成功打开数据库")
c=con.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语句
con.commit() #提交数据库操作
con.close() #关闭数据库连接
c.close() #关闭指针对象(游标)
print("成功建表")

3.插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
con=sqlite3.connect("test.db")
print("成功打开数据库")
c=con.cursor() #获取游标(游标,操作数据库的对象)
sql1='''
insert into company (id,name,age,address,salary)
values(1,'张三',32,'成都',8000);
'''
sql2='''
insert into company (id,name,age,address,salary)
values(2,'李四',30,'重庆',15000);
'''
c.execute(sql1) #执行sql语句
c.execute(sql2) #执行sql语句
con.commit() #提交数据库操作
con.close() #关闭数据库连接
c.close() #关闭指针对象(游标)
print("插入数据完毕")

4.查询数据

1
2
3
4
5
6
7
8
9
10
11
12
13
con=sqlite3.connect("test.db")
print("成功打开数据库")
c=con.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")
con.close() #关闭数据库连接
c.close() #关闭指针对象(游标)
print("查询完毕")

查询出来的每条结果都是一个tuple类型的数据,这些tuple组成了一个tuple

因为爬虫应用数据库最多的就是插入和查询,删和改用的较少,只要改下sql语句就可以了

如果不确定sql语句写的对不对,可以在右键数据表,点击Edit Source

image-20210516154617319

然后在弹出的页面里写sql语句,右键执行(Execute)一下看看结果对不对

应用sqlite3爬取豆瓣电影top250数据到数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# -*-coding=utf-8-*-
# @Time : 2021/5/11 14:15
# @Auther : Tianze
# @Email : 1252448508@qq.com
# @File : sqlite-crawler.py
# @Software : PyCharm

from bs4 import BeautifulSoup #网页解析,获取数据
import requests #HTTP请求
import re #正则表达式,进行文字匹配
import xlwt #进行excel操作
import sqlite3 #进行SQLite数据库操作

def main():
url="https://movie.douban.com/top250?start="
#1.爬取网页
datalist=getData(url)
#2.逐一解析数据,边爬边解析
#3.保存数据
#savepath=".\\豆瓣电影Top250.xls"
dbpath="movie.db"
#saveData(datalist,savepath) #按住ctrl点击函数,可以快速跳转定位
saveData2db(datalist,dbpath)

#电影链接的规则
findlink=re.compile(r'<a href="(.*?)">') #.*?表示非贪婪模式
#电影图片
findImgSrc=re.compile(r'<img.*src="(.*?)"',re.S) #返回括号中的内容,其他内容起到定位效果,re.s不忽略换行符
#电影名
findTitle=re.compile(r'<span class="title">(.*?)</span>')
#电影评分
findRating=re.compile(r'<span class="rating_num" property="v:average">(.*?)</span>')
#评价人数
findJudge=re.compile(r'<span>(\d*)人评价</span>')
#电影寓意
findInt=re.compile(r'<span class="inq">(.*?)</span>')
#电影相关信息
findBd=re.compile(r'<p class="">(.*?)</p>',re.S)


#爬取网页
def getData(url):
datalist=[]
for i in range(0,10): #调用10次
url1=url+str(i*25)
html=getURL(url1)

#2.逐一解析数据,边爬边解析
soup=BeautifulSoup(html,"html.parser")
for item in soup.find_all("div",class_="item"): #查找符合要求的字符串,形成列表
#print(item) #测试,查看电影item信息
data=[] #保存一部电影的所有信息
item=str(item)

#电影链接:
link=re.findall(findlink,item)[0] #通过正则表达式查找指定字符串
data.append(link) #添加电影链接
imgSrc=re.findall(findImgSrc,item)[0]
data.append(imgSrc) #添加图片链接
titles=re.findall(findTitle,item) #片名可能只有一个中文名,没有外国名
if len(titles)==2:
ctitle=titles[0]
data.append(ctitle) #添加中文名
otitle=titles[1].replace("/","") #去掉无关符号
otitle=otitle.strip() #去掉首位空格
data.append(otitle) #添加外国名
else:
data.append(titles[0])
data.append(" ") #外国名字留空
rating=re.findall(findRating,item)[0]
data.append(rating) #添加评分
judgeNum=re.findall(findJudge,item)[0]
data.append(judgeNum) #添加评价人数
inq=re.findall(findInt,item)
if len(inq)!=0:
inq=inq[0].replace("。",'') #去掉句号
data.append(inq) #添加寓意
else:
data.append(" ") #留空
bd=re.findall(findBd,item)[0]
bd=re.sub("<br(\s)?/>(\s+)?"," ",bd) #替换<br/>
bd=re.sub("/"," ",bd) #替换/
bd=re.sub("\s+"," ",bd) #替换空格,否则出现NBSP
data.append(bd.strip()) #去掉前后的空格
datalist.append(data) #把处理好的一部电影信息放入datalist
return datalist

#得到指定URL的网页内容
def getURL(url):
headers={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
}
html=""
try:
res=requests.get(url=url,headers=headers)
html=res.text
#print(html)
except requests.HTTPError as err:
if hasattr(err,"code"):
print(err.code)
if hasattr(err,"reason"):
print(err.reason)
return html

#保存数据
def saveData(datalist,savepath):
print("[*]开始爬取")
book=xlwt.Workbook(encoding="utf-8") #创建workbook对象
sheet=book.add_sheet("豆瓣电影top250") #创建工作表
col=('电影链接','图片链接','电影中文名','电影外国名','评分','评价人数','寓意','相关信息')
for i in range(len(col)):
sheet.write(0,i,col[i]) #列名
for i in range(0,250):
print("第{}条".format(i+1))
data=datalist[i]
for j in range(len(col)):
sheet.write(i+1,j,data[j])
book.save(savepath) #保存数据表


def saveData2db(datalist,dbpath):
init_db(dbpath)
con=sqlite3.connect(dbpath)
cursor=con.cursor()

for data in datalist:
for index in range(len(data)):
if(index==4 or index==5):
continue
data[index]='"'+data[index]+'"'
sql='''insert into movie250(
info_link,pic_link,cname,ename,score,rated,introduction,info)
values(%s)'''%",".join(data)
#print(sql)
cursor.execute(sql)
con.commit()
cursor.close()
con.close()

#初始化数据库
def init_db(dbpath):
# 创建数据表
# numeric可以存小数
sql='''
create table movie250(
id integer primary key autoincrement,
info_link text,
pic_link text,
cname varchar,
ename varchar,
score numeric,
rated numeric,
introduction text,
info text
)
'''
con=sqlite3.connect(dbpath)
cursor=con.cursor()
cursor.execute(sql)
con.commit()
con.close()

if __name__=="__main__":
main()
#init_db("movietest.db")
print("[*]导入数据库完毕")
#getData("https://movie.douban.com/top250?start=")

结果:

image-2021513

遇到的问题

英文名(ename)和信息(info)里出现NBSP

image-20210513164234326

如图所示

image-20210513164504251

爬取到的代码里的确有nbsp编码的空格,所以在正则提取处理的时候要去掉空格

英文名因为只有首尾有空格,所以用strip()函数就可以,info那里的空格在中间,所以用bd=re.sub("\s+"," ",bd)把空格字符替换成空格即可

image-20210513165027687

参考

https://www.bilibili.com/video/BV12E411A7ZQ?p=26

https://www.bilibili.com/video/BV12E411A7ZQ?p=27

https://www.cnblogs.com/fatcat132006/p/4081576.html

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2020-2021 Blog of Tianze

请我喝杯咖啡吧~

支付宝
微信