python爬虫简介

  • 网络爬虫,是一种按照一定规则,自动抓取互联网信息的程序或脚本。由于互联网数据的多样性和资源的有限性,根据用户需求定向抓取相关网页并分析。
  • 爬虫的本质:模拟浏览器打开网页,捕获网页中我们想要的那部分数据。

从索引区出发——>网页(将抓取到的网页放到历史库中进行处理)——>临时库(不符合规则的清理,符合规则的进入索引区)——>索引区(在索引区进行分类,归档,排序,然后反馈到用户)

——>搜索引擎查询

基本流程

  • 准备工作(通过浏览器查看分析目标网页)
  • 获取数据(通过http库向目标站点发起请求)
  • 解析内容(得到的内容可能是html,json。可以用页面解析库,正则表达式进行解析)
  • 保存数据(存为文本,保存到数据库,或者保存特定个数的文件。)
  • 豆瓣电影网址:https://movie.douban.com/top250

准备工作

url分析

  • 页面包括250条电影数据,分10页,每页25条
  • 每页的url不同之处:最后的数值 = (页数-1) * 25

分析页面

  • 借助Chrome开发者工具(F12)来分析页面,在Elements下找到需要的数据位置.

编码规范

  • 一般python程序第一行需加入以下内容(这样代码中可以包含文字)
1
#-*-coding:utf-s-*-  或者   coding=utf-8
  • python文件中可以加入main函数可以用于测试程序(可以控制代码的程序和流程)
1
2
if __name__ == "__main__":   # 当程序执行时
# 调用函数
1
2
3
4
5
6
def main():
print("hello")

if __name__ == "__main__": # 当程序执行时
# 调用函数
main()
  • 引入自定义模块
1
2
3
4
5
6
7
8
9
10
11
# 引入自定义模块
from test1 import t1

# 引入系统模块
import sys
import os

# 引入第三方模块
import re

print(t1)

引入模块

  • pycharm终端进行安装
  • setting——>project interpreter
1
2
3
4
5
import bs4   # 网页解析,获取数据
import re # 正则表达式,进行文字匹配
import urllib.request,urllib.error # 制定url,获取数据
import xlwt # 进行excel操作
import sqlite3 # 进行sqllite数据库操作

思路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def main():
baseurl = "https://movie.douban.com/top250?start="
datelist = getData(baseurl)
savepath = ".\\豆瓣电影Top.xls"
# 1.爬取网页
# 2.逐一解析数据
# 3.保存数据

def getData(baseurl):
datalist = []
# 2.逐一解析数据
return datalist

def saveData(baseurl):
# 3.保存数据
pass


if __name__ == "__main__": # 当程序执行时
# 调用函数
main()

获取数据

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
from bs4 import BeautifulSoup   # 网页解析,获取数据
import re # 正则表达式,进行文字匹配
import urllib.request,urllib.error # 制定url,获取数据
import xlwt # 进行excel操作
import sqlite3 # 进行sqllite数据库操作

def main():
baseurl = "https://movie.douban.com/top250?start="
# 爬取网页
datelist = getData(baseurl)
savepath = ".\\豆瓣电影Top.xls"
# 保存数据
# saveData(savepath)



def getData(baseurl):
datalist = []
for i in range(0,10): # 调用获取信息的函数:10次
url = baseurl + str(i * 25)
html = askURL(url) # 保存获取到的网页源码

return datalist

# 得到指定一个url的网页内容
def askURL(url):
head = { # 模拟浏览器头部信息(伪装)
"User-Agent": "Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 97.0.4692.71Safari / 537.36"
}
# 用户代理,告诉豆瓣,我们是什么类型的及其,浏览器(本质是告诉浏览器。我们可以接收什么水平的信息)

request = urllib.request.Request(url,headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
print(html)
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)

return html

def saveData(baseurl):
pass


if __name__ == "__main__": # 当程序执行时
# 调用函数
main()

解析内容

  • 使用BeautifulSoup定位特定的标签位置
  • 使用正则表达式找到具体的内容
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
from bs4 import BeautifulSoup   # 网页解析,获取数据
import re # 正则表达式,进行文字匹配
import urllib.request,urllib.error # 制定url,获取数据
import xlwt # 进行excel操作
import sqlite3 # 进行sqllite数据库操作

def main():
baseurl = "https://movie.douban.com/top250?start="
# 爬取网页
datelist = getData(baseurl)
savepath = ".\\豆瓣电影Top.xls"
# 保存数据
# saveData(savepath)

# 影片详情的规则
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>')
#概况
findInq = re.compile(r'<span class="inq">(.*)</span>')
#相关内容
findBd = re.compile(r'<p class="">(.*?)</p>\n<div',re.S)



def getData(baseurl):
datalist = []
for i in range(0,10): # 调用获取信息的函数:10次
url = baseurl + str(i * 25)
html = askURL(url) # 保存获取到的网页源码

# 逐一解析数据
soup = BeautifulSoup(html,"html.parser")
for item in soup.find_all('div',class_="item"): # 查找符合要求的字符串,形成列表,class加下划线,表示属性值
# print(item) # 测试:查看一部电影的所有信息
data = []
item = str(item)

# 影片详情的超链接
link = re.findall(findLink,item)[0] # re库通过正则表达式查早指定的字符串
data.append(link) # 添加链接

imgSrc = re.findall(findImgSrc,item)[0]
data.append(imgSrc) # 添加图片

titles = re.findall(findTitle,item) # 片面,可能只有一个中文名
if(len(titles) == 2):
ctitie = titles[0]
data.append(ctitie) # 添加中文名
otitle = titles[1].replace("/","") # 去掉无关符号
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(findInq,item)
if len(inq) != 0:
inq = inq[0].replace("。",",") # 去掉句号
data.append(inq)
else:
data.append(inq) # 添加概述

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) # 将处理好的一部电影信息放入datalist
print(datalist)
return datalist

# 得到指定一个url的网页内容
def askURL(url):
head = { # 模拟浏览器头部信息(伪装)
"User-Agent": "Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 97.0.4692.71Safari / 537.36"
}
# 用户代理,告诉豆瓣,我们是什么类型的及其,浏览器(本质是告诉浏览器。我们可以接收什么水平的信息)

request = urllib.request.Request(url,headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-")
# print(html)
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)

return html

def saveData(baseurl):
pass


if __name__ == "__main__": # 当程序执行时
# 调用函数
main()

保存数据

  • 以utf-8编码创建一个Excel对象
  • 创建一个sheet表
  • 往单元格写入内容
  • 保存表格
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
# -*- codeing = utf-8 -*-
# @Time : 2022/1/28 21:06
# @Author : bkys
# @File : spider.py
# @Software : PyCharm


from bs4 import BeautifulSoup # 网页解析,获取数据
import re # 正则表达式,进行文字匹配
import urllib.request,urllib.error # 制定url,获取数据
import xlwt # 进行excel操作
import sqlite3 # 进行sqllite数据库操作

def main():
baseurl = "https://movie.douban.com/top250?start="
# 爬取网页
datalist = getData(baseurl)
savepath = ".\\豆瓣电影Top.xls"
# 保存数据
saveData(datalist,savepath)

# 影片详情的规则
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>')
#概况
findInq = re.compile(r'<span class="inq">(.*)</span>')
#相关内容
findBd = re.compile(r'<p class="">(.*?)</p>\n<div',re.S)



def getData(baseurl):
datalist = []
for i in range(0,10): # 调用获取信息的函数:10次
url = baseurl + str(i * 25)
html = askURL(url) # 保存获取到的网页源码

# 逐一解析数据
soup = BeautifulSoup(html,"html.parser")
for item in soup.find_all('div',class_="item"): # 查找符合要求的字符串,形成列表,class加下划线,表示属性值
# print(item) # 测试:查看一部电影的所有信息
data = []
item = str(item)

# 影片详情的超链接
link = re.findall(findLink,item)[0] # re库通过正则表达式查早指定的字符串
data.append(link) # 添加链接

imgSrc = re.findall(findImgSrc,item)[0]
data.append(imgSrc) # 添加图片

titles = re.findall(findTitle,item) # 片面,可能只有一个中文名
if(len(titles) == 2):
ctitie = titles[0]
data.append(ctitie) # 添加中文名
otitle = titles[1].replace("/","") # 去掉无关符号
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(findInq,item)
if len(inq) != 0:
inq = inq[0].replace("。",",") # 去掉句号
data.append(inq)
else:
data.append(inq) # 添加概述

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) # 将处理好的一部电影信息放入datalist
return datalist

# 得到指定一个url的网页内容
def askURL(url):
head = { # 模拟浏览器头部信息(伪装)
"User-Agent": "Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 97.0.4692.71Safari / 537.36"
}
# 用户代理,告诉豆瓣,我们是什么类型的及其,浏览器(本质是告诉浏览器。我们可以接收什么水平的信息)

request = urllib.request.Request(url,headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-")
# print(html)
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)

return html

def saveData(datalist,savapath):
book = xlwt.Workbook(encoding="utf-8",style_compression=0) # 创建workbook对象
sheet = book.add_sheet("豆瓣电影Top250",cell_overwrite_ok=True) # 创建工作表
col = ("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息")
for i in range(0,8):
sheet.write(0,i,col[i]) # 列名
for i in range(0,250):
print("第%d条" %(i+1))
data = datalist[i]
for j in range(0,8):
sheet.write(i+1,j,data[j])

book.save(savapath)



if __name__ == "__main__": # 当程序执行时
# 调用函数
main()
print("爬取完毕")

urllib扩展

获取一个get请求

1
2
3
4
import urllib.request

response = urllib.request.urlopen("http://www.baidu.com")
print(response.read().decode('utf-8')) # 对获得到的网页源码进行utf-8解码

获取一个post请求

  • httpbin.org(用于测试)
1
2
3
4
5
6
7
8
import urllib.request
import urllib.parse # 解析器,解析键值对

# 给post传递表单信息
# data = bytes() # 转换成二进制的数据包
data = bytes(urllib.parse.urlencode({"hello":"world"}),encoding="utf-8")
response = urllib.request.urlopen("http://httpbin.org/post",data= data)
print(response.read().decode("utf-8"))

超时处理(418被发现)

1
2
3
4
5
6
7
import urllib.request

try:
response = urllib.request.urlopen("http://httpbin.org/get",timeout=0.01)
print(response.read().decode("utf-8"))
except urllib.error.URLError as e:
print("time out!")

获取header

1
2
3
4
5
import urllib.request

response = urllib.request.urlopen("http://www.baidu.com")
print(response.getheaders()) # 要拿具体的header,使用getheader
print(response.getheader("Server"))

Bs4

BeautifulSoup简介

BeautifulSoup将复杂的html文档转换成一个复杂的树形结构,每个节点都是python对象,所有的对象可分为四类。

  • Tag 标签及其内容:只能拿到它所找到的第一个内容
  • NavigableString 标签里的内容(字符串)
  • BeautifulSoup 整个文档
  • Comment 这是一个特殊的NavigableString,输出的内容不包含注释符号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from bs4 import BeautifulSoup
import urllib.request

file = urllib.request.urlopen("http://www.baidu.com")
html = file.read()
bs = BeautifulSoup(html,"html.parser")

print(bs.title) # 拿到整个title标签
print(bs.title.string) # 拿到title标签内的内容
print(type(bs.title.string)) # 标签内的内容,字符串

print(bs.a.attrs) # 以字典形式展示标签中的属性

print(type(bs)) # 表示整个文档
print(bs.name) # 文档
print(bs) # 打印整个文档

print(bs.a.string) # 去掉注释
print(type(bs.a.string)) # 是一个特殊的NavigableString,不包含注释部分

文档的遍历

1
2
3
4
5
6
7
8
9
from bs4 import BeautifulSoup
import urllib.request

file = urllib.request.urlopen("http://www.baidu.com")
html = file.read().decode('utf-8')
bs = BeautifulSoup(html,"html.parser")

# print(bs.head.contents) # 返回一个列表
print(bs.head.contents[1])

文档的搜索

  • 字符串过滤:会查找与字符串完全匹配的内容
1
2
3
4
5
6
7
8
9
10
from bs4 import BeautifulSoup
import urllib.request

file = urllib.request.urlopen("http://www.baidu.com")
# file = open(response.decode('utf-8'))
html = file.read().decode('utf-8')
bs = BeautifulSoup(html,"html.parser")

t_list = bs.find_all("a") # 返回一个列表,这个列表包含所有的a标签
print(t_list)
  • 正则表达式搜索:使用search()方法来匹配内容
1
2
3
4
5
6
7
8
9
10
from bs4 import BeautifulSoup
import urllib.request
import re

file = urllib.request.urlopen("http://www.baidu.com"))
html = file.read().decode('utf-8')
bs = BeautifulSoup(html,"html.parser")

t_list = bs.find_all(re.compile("a")) # 所有包含a的标签,捕获标签及其内容
print(t_list)
  • 传入一个函数,根据函数的要求来搜索
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from bs4 import BeautifulSoup
import urllib.request
file = urllib.request.urlopen("http://www.baidu.com")

html = file.read().decode('utf-8')

bs = BeautifulSoup(html,"html.parser")

def name_is_exists(tag):

return tag.has_attr("name") # 搜索有name标签的

t_list = bs.find_all(name_is_exists)

# print(t_list)

for item in t_list:

print(t_list) # 以列表形式打印
  • kwargs 参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from bs4 import BeautifulSoup
import urllib.request

file = urllib.request.urlopen("http://www.baidu.com")
html = file.read().decode('utf-8')
bs = BeautifulSoup(html,"html.parser")

# t_list = bs.find_all(id="head")

# t_list = bs.find_all(class_=True) # 包含class及其子内容

# print(t_list)
for item in t_list:
print(item) # 以打印head中的所有子内容
  • text参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from bs4 import BeautifulSoup
import urllib.request
import re

file = urllib.request.urlopen("http://www.baidu.com")
html = file.read().decode('utf-8')
bs = BeautifulSoup(html,"html.parser")

# t_list = bs.find_all(text = "hao123")
t_list = bs.find_all(text = ["hao123","地图","贴吧"])

t_list = bs.find_all(text = re.compile("\d")) # 应用正则表达式来查找包含特定文本的内容

for item in t_list:
print(item)
  • limit参数
1
2
3
4
5
6
7
8
9
10
11
12
13
from bs4 import BeautifulSoup
import urllib.request
import re

file = urllib.request.urlopen("http://www.baidu.com")
html = file.read().decode('utf-8')
bs = BeautifulSoup(html,"html.parser")


t_list = bs.find_all("a", limit= 3) # limit在得到信息时限制条数

for item in t_list:
print(item)
  • css选择器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from bs4 import BeautifulSoup
import urllib.request
import re

file = urllib.request.urlopen("http://www.baidu.com")
html = file.read().decode('utf-8')
bs = BeautifulSoup(html,"html.parser")

# t_list = bs.select("title") # 通过标签来查找

# t_list = bs.select(".mnav") # 通过类名字来查找

t_list = bs.select("#u1") # 通过id查找

# 通过属性查找
# 通过子标签查找
# ...

for item in t_list:
print(item)

正则表达式

操作符 说明 实例
. 表示任何单个字符
[ ] 字符集 [abc] 表示a,b,c
[^ ] 非字符集 [^abc] 表示非a,b,c
* 前一个字符0次或无限次扩展 abc* 表示ab,abc,abcc,abccc等
+ 前一个字符1次或无限次扩展 abc+ 表示abc,abcc,abccc等
? 前一个字符0次或1次扩展 abc? 表示ab,abc
|
{m} 扩展前一个字符m次 ab{2} 表示abcc
{m,n} 扩展前一个字符m至n次 ab{1,2}c 表示abc,abbc
^ 匹配字符串开头
$ 匹配字符串结尾
() 分组标记,内部只能使用 | 操作符 (a|b) 表示a,b
\d 数字,等价于[0-9]
\w 单词字符,等价于[A-Z,a-z,0-9,_]

Re库主要功能函数

函数 说明
re.search() 在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象
re.match() 从第一个字符串开始位置匹配正则表达式,返回match对象
re.findall() 搜索字符串,以列表类型返回全部能匹配的子串
re.split() 将一个字符串按照正则表达式匹配结果进行性分割,返回列表类型
re.finditer() 搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
re.sub() 在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

修饰符

修饰符 描述
re.l 使匹配对大小写不敏感
re.L 做本地化识别(Locale-aware)匹配
re.M 多行匹配,影响^和$
re.S 使.匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符,这个影响\w,\W,\b,\B
re.X 该标志通过给予你更灵活的格式以便将正则表达式写的更利与理解

实例

  • search()方法
1
2
3
4
5
6
7
8
9
10
11
12
import re

# 创建模式对象
pat = re.compile("AA") # 此处的AA是正则表达式,用来去验证其他的字符串

# m = pat.search("CBAA") # search字符串被校验内容
m = pat.search("AACBAA") # search方法只能搜索找到的第一组,进行比对查找

# 不创建模式对象
m = re.compile("asd,Aasd") # 前面的字符串是规则(模板),后面的字符串是被校验的对象

print(m)
  • findall()方法
1
2
3
4
5
6
7
import re

# m = re.findall("a", "asdASDasd") # 前面的字符串是规则(正则表达式),后面的字符串是被校验的对象
# m = re.findall("[A-Z]", "asdASDasdAWM")
m = re.findall("[A-Z]+", "asdASDasdAWM")

print(m)
  • sub方法
1
2
3
import re

print(re.sub("a","A","asdASDawm")) # 在第三个字符串中找到a,用A替换
  • 建议在正则表达式中被比较字符串前面加上r,不用担心转义字符的问题
1
2
3
4
5
a = "\abc\'"
print(a)

a = r"\abc\'"
print(a)

SQLite

连接数据库

1
2
3
4
# 1.连接数据库
conn = sqlite3.connect("test.db") # 打开或创建数据库文件

print("成功打开数据库")

创建数据表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1.连接数据库
conn = sqlite3.connect("test.db") # 打开或创建数据库文件

print("成功打开数据库")

# 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() # 关闭数据库链接

print("成功建表")

插入数据

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
import sqlite3


# 1.连接数据库
conn = sqlite3.connect("test.db") # 打开或创建数据库文件

print("成功打开数据库")

# 2.创建数据表
c = conn.cursor() # 获取游标

sql1 = '''
insert into company (id,name,age,address,salary)
values(1,"张三" ,"19","西安","10000")
'''

sql2 = '''
insert into company (id,name,age,address,salary)
values(2,"bkys" ,"19","西安","1000000")
'''

c.execute(sql1) # 执行sql语句
c.execute(sql2)
conn.commit() # 提交数据库操作
conn.close() # 关闭数据库链接

print("插入数据完毕")

查询数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1.连接数据库
conn = sqlite3.connect("test.db") # 打开或创建数据库文件

print("成功打开数据库")

# 2.创建数据表
c = conn.cursor() # 获取游标

sql = "select id,name,address,salary from company"

cursor = c.execute(sql)

for row in cursor:
print("id = ", row[0])
print("name = ", row[1])
print("address = ", row[2])
print("salary = ", row[3], "\n")

conn.close() # 关闭数据库链接

print("查询完毕")
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
def saveData2DB(datalist,dbpath):
init_db(dbpath)
conn =sqlite3.connect(dbpath)
cur = conn.cursor()

for data in datalist:
for index in range(len(data)):
data[index] = '"' + data[index] + '"'
sql = '''
insert into movie250 (
info_link, pic_link, cname, ename, score, rated, introduction, info)
values(%s)''' % ",".join(data)
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 varchar ,
ename varchar ,
score numeric ,
rated numeric ,
instroduction text,
info text
)
'''
conn = sqlite3.connect(dbpath)
cursor = conn.cursor()
cursor.execute(sql)
conn.commit()
conn.close()

将豆瓣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
from bs4 import BeautifulSoup    #网页解析,获取数据
import re #正则表达式,进行文字匹配
import urllib.request,urllib.error #指定URL,获取网页数据
import xlwt #进行Excel操作
import sqlite3 #进行sql数据库操作


#创建正则表达式对象
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>') #影片评价人数的规则
findInq = re.compile(r'<span class="inq">(.*)</span>') #影片概况的规则
findBd = re.compile(r'<p class="">(.*?)</p>',re.S) #影片导演的规则

def main():
baseurl = "https://movie.douban.com/top250?start="
# 爬取网页
datalist = getData(baseurl)
# 保存数据
dbpath = "movie.db"
saveData(datalist,dbpath)


#爬取网页
def getData(baseurl):
datalist = []
for i in range(0,10):
url = baseurl + str(i*25)
html = askURL(url) #保存从网页中获取到的源码

#逐个解析数据
soup = BeautifulSoup(html,"html.parser")
for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,形成列表
#print(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]
otitle = titles[1].replace("/","") #替换符号
data.append(ctitle)
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(findInq,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)
bd = re.sub('/',"",bd)
data.append(bd.strip()) #去空格

datalist.append(data)
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/74.0.3729.108 Safari/537.36"}
request = urllib.request.Request(url,headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
#print(html)
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e,"reason"):
print(e.reason)

return html

#创建一个数据表
def createTable(dbpath):
sql = '''
CREATE TABLE movie250
(
id integer primary key autoincrement,
info_link TEXT,
pic_link TEXT,
cname VARCHAR(255),
oname VARCHAR(255),
score FLOAT,
rated NUMERIC,
instroduction TEXT,
info text
);
'''
conn = sqlite3.connect(dbpath)
cursor = conn.cursor()
cursor.execute(sql)
conn.commit()
conn.close()

#保存数据
def saveData(datalist,dbpath):
createTable(dbpath)
conn = sqlite3.connect(dbpath)
cur = conn.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,
oname,
score,
rated,
instroduction,
info
) VALUES(%s)
'''%",".join(data) # 表名 字段名 插入的值
cur.execute(sql)
conn.commit()
cur.close()
conn.close()

#入口
if __name__ == '__main__':
main()
print("爬取完毕")
  • 更新后的版本
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
import requests
from bs4 import BeautifulSoup

def get_movie_info(movie):
info = movie.select('div[class="hd"]')[0]
title = info.select('span[class="title"]')[0].text
link = info.a['href']
rating = movie.select('span[class="rating_num"]')[0].text
comment_num = movie.select('div[class="star"] > span')[3].text[:-3]
return {
'title': title,
'link': link,
'rating': rating,
'comment_num': comment_num
}

def get_movie_list(start):
url = f'https://movie.douban.com/top250?start={start}&filter='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
movies = soup.select('div[class="item"]')
movie_list = []
for movie in movies:
movie_list.append(get_movie_info(movie))
return movie_list

def get_top205():
movie_list = []
for start in range(0, 205, 25):
movie_list += get_movie_list(start)
return movie_list

if __name__ == '__main__':
movie_list = get_top205()
for movie in movie_list:
print(movie)