2022年 11月 8日

python豆瓣Top250数据分析

 python基础学习

Python基础语法_aiqq136的博客-CSDN博客

python_webcrawler

以下内容

数据可视化

数据可视化_aiqq136的博客-CSDN博客

一.python爬虫

1.任务介绍

需求分析

爬取豆瓣电影Top250的基本信息,包括电影的名称、豆瓣评分、评价数、电影概况、电影链接等。

https://movie.douban.com/top250

2.爬虫初识

什么是爬虫?

网络爬虫,是一种按照一定规则,自动抓取互联网信息的程序或者脚本。

由于互联网数据的多样性和资源的有限性,根据用户需求定向抓取相关网页并分析已成为如今主流的爬取策略。

爬虫可以做什么?

你可以爬取妹子的图片,爬取自己想看的视频等等,只要你能通过浏览器访问的数据都可以通过爬虫获取。

爬虫的本质是什么?

模拟浏览器打开网页,获取网页中我们想要的那部分数据。

3.基本流程

准备工作

通过浏览器查看分析目标网页,学习编程基础规范。

获取数据

通过HTTP库向目标站点发起请求,请求可以包含额外的header等信息,

如果服务器能正常响应,会得到一个Response,便是所要获取的页面内容。

解析内容

得到的内容可能是HTML、json等格式,可以用页面解析库、正则表达式等进行解析。

保存数据

保存形式多样,可以存为文本,也可以保存到数据库,或者保存特定格式的文件。

二.准备工作

1.网页的路径规律

https://movie.douban.com/top250?start=0        从第1个开始展示

https://movie.douban.com/top250?start=25            从第26个开始展示

2.URL分析

页面包括250条电影数据,分10页,每页25条

每页的URL的不同之处:最后的数值=(页数- 1)* 25

3.分析页面

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

Select an element in the page to inspect it Ctrl + Shift +C

在network下可以看刷新网址以后的所有访问请求的时间线

Headers:当前这一次访问给浏览器发送的信息

User-Agent:浏览器信息

需要登录的网页 要用到cookie

4.编码规范

1.一般Python程序第一行需要加入

#-*- coding: utf-8 -*-或者# coding=utf-8

这样可以在代码中包含中文

2.在Python中,使用函数实现单一功能或相关联功能的代码段,可以提高可读性和代码重复利用率,

函数代码块以def关键词开头,后接空格、函数标识符名称、圆括号()、冒号:

括号中可以传入参数,函数段缩进(Tab或四个空格,只能任选一种),

return用于结束函数,可以返回一个值,也可以不带任何表达式(表示返回None )

3.Python文件中可以加入main函数用于测试程序

if __name__ == "__main__":

有利于管理函数的执行顺序
例子:

  1. #-*- coding: utf-8 -*-
  2. def main():
  3. print("hello")
  4. if __name__ == "__main__": #当程序执行时
  5. #调用函数
  6. main()

4.Python使用#添加注释,说明代码(段)的作用

三.引入模块

1.模块( module )

用来从逻辑上组织Python代码(变量、函数、类),本质就是py文件,提高代码的可维护性。

Python使用import来导入模块,如import sys

例子:
test1文件夹里面有t1.py

  1. def add(a,b):
  2. return a+b

而我想在test2文件夹的t2.py中调用t1中的函数

#引入自定义的模块

  1. from test1 import t1
  2. print(t1.add(2,3))

#引入系统的模块

  1. import sys
  2. import os

#引入第三方模块(这些都是这个项目要使用的模块)
 

  1. import bs4 #网页解析,获取数据
  2. import re #正则表达式,进行文字匹配
  3. import urllib.request,urllib.error #制定URL,获取网络数据
  4. import xlwt #进行excel操作
  5. import sqlite3 #进行SQLite数据库操作

由于我使用的工具为vs2019,它的第三方模块的加载方式为

 在这里输入想查找的包的名字,例如bs4

 点击pip install bs4就可以了

现在程序为

  1. #-*- coding: utf-8 -*-
  2. from bs4 import BeautifulSoup #网页解析,获取数据
  3. import re #正则表达式,进行文字匹配
  4. import urllib.request,urllib.error #制定URL,获取网络数据
  5. import xlwt #进行excel操作
  6. import sqlite3 #进行SQLite数据库操作
  7. def main():
  8. baseurl="https://movie.douban.com/top250"
  9. #1.爬取网页
  10. datalist=getData(baseurl)
  11. savepath=".\\豆瓣电影Top250.xls" #当前文件夹下
  12. #3.保存数据
  13. saveData(savepath)
  14. #爬取网页
  15. def getData(baseurl):
  16. datelist=[]
  17. #2.逐一解析数据
  18. return datalist
  19. #保存数据
  20. def saveData(savepath):
  21. print("save.....")
  22. if __name__ == "__main__": #当程序执行时
  23. #调用函数
  24. main()

2.获取数据

Python一般使用urllib库获取页面

获取页面数据

  • 对每一个页面,调用askURL函数获取页面内容
  • 定义一个获取页面的函数askURL,传入一个url参数,表示网址,如https:// movie.douban.com/top250?start=0
  • urllib.Request生成请求:urllib.urlopen发送请求获取响应; rcad获取页面内容
  • 在访问页面时经常会出现错误,为了程序正常运行,加入异常捕获try…except…语句

 urllib测试

urllib测试_aiqq136的博客-CSDN博客

获取数据

得到一个指定URL的网页内容

  1. #-*- coding: utf-8 -*-
  2. from bs4 import BeautifulSoup #网页解析,获取数据
  3. import re #正则表达式,进行文字匹配
  4. import urllib.request,urllib.error #制定URL,获取网络数据
  5. import xlwt #进行excel操作
  6. import sqlite3 #进行SQLite数据库操作
  7. def main():
  8. baseurl="https://movie.douban.com/top250?start="
  9. #1.爬取网页
  10. datalist=getData(baseurl)
  11. savepath=".\\豆瓣电影Top250.xls" #当前文件夹下
  12. #3.保存数据
  13. #saveData(savepath)
  14. askURL("https://movie.douban.com/top250?start=")
  15. #爬取网页
  16. def getData(baseurl):
  17. datalist=[]
  18. #2.逐一解析数据
  19. return datalist
  20. #得到一个指定URL的网页内容
  21. def askURL(url):
  22. #模拟浏览器头部信息,向豆瓣服务器发送信息
  23. head={"User-Agent":" Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"}
  24. #用户代理,表示告诉豆瓣服务器,我们是什么类型的机器,浏览器(本质上是高速浏览器,我们可以接受什么水平的信息)
  25. request=urllib.request.Request(url,headers=head)
  26. html=""
  27. try:
  28. response=urllib.request.urlopen(request)
  29. html=response.read().decode("utf-8")
  30. print(html)
  31. except urllib.error.URLError as e: #捕获错误
  32. if hasattr(e,"code"):
  33. print(e.code) #打印错误代码
  34. if hasattr(e,"reason"):
  35. print(e.reason) #打印错误原因
  36. return html
  37. #保存数据
  38. def saveData(savepath):
  39. print("save.....")
  40. if __name__ == "__main__": #当程序执行时
  41. #调用函数
  42. main()

查看内容,发现得到网页的数据了

爬取网页

用循环构造换页

  1. #爬取网页
  2. def getData(baseurl):
  3. datalist=[]
  4. for i in range(0,10): #调用获取页面信息的函数,10次
  5. url=baseurl + str(i*25)
  6. html=askURL(url) #保存获取到的网页源码
  7. #2.逐一解析数据
  8. return datalist

现阶段代码

  1. #-*- coding: utf-8 -*-
  2. from bs4 import BeautifulSoup #网页解析,获取数据
  3. import re #正则表达式,进行文字匹配
  4. import urllib.request,urllib.error #制定URL,获取网络数据
  5. import xlwt #进行excel操作
  6. import sqlite3 #进行SQLite数据库操作
  7. def main():
  8. baseurl="https://movie.douban.com/top250?start="
  9. #1.爬取网页
  10. datalist=getData(baseurl)
  11. savepath=".\\豆瓣电影Top250.xls" #当前文件夹下
  12. #3.保存数据
  13. #saveData(savepath)
  14. askURL("https://movie.douban.com/top250?start=")
  15. #爬取网页
  16. def getData(baseurl):
  17. datalist=[]
  18. for i in range(0,10): #调用获取页面信息的函数,10次
  19. url=baseurl + str(i*25)
  20. html=askURL(url) #保存获取到的网页源码
  21. #2.逐一解析数据
  22. return datalist
  23. #得到一个指定URL的网页内容
  24. def askURL(url):
  25. #模拟浏览器头部信息,向豆瓣服务器发送信息
  26. head={"User-Agent":" Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"}
  27. #用户代理,表示告诉豆瓣服务器,我们是什么类型的机器,浏览器(本质上是高速浏览器,我们可以接受什么水平的信息)
  28. request=urllib.request.Request(url,headers=head)
  29. html=""
  30. try:
  31. response=urllib.request.urlopen(request)
  32. html=response.read().decode("utf-8")
  33. print(html)
  34. except urllib.error.URLError as e: #捕获错误
  35. if hasattr(e,"code"):
  36. print(e.code) #打印错误代码
  37. if hasattr(e,"reason"):
  38. print(e.reason) #打印错误原因
  39. return html
  40. #保存数据
  41. def saveData(savepath):
  42. print("save.....")
  43. if __name__ == "__main__": #当程序执行时
  44. #调用函数
  45. main()

补充BeautifulSoup用于html文件解析

BeautifulSoup用于html文件解析_aiqq136的博客-CSDN博客

补充re模块:正则表达式

re模块:正则表达式_aiqq136的博客-CSDN博客

正则提取

拿到每一个电影的相关信息

  1. #2.逐一解析数据
  2. soup=BeautifulSoup(html,"html.parser")
  3. for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,形成列表
  4. print(item)

 

搞出第一页影片的超链接

  1. #影片详情的链接的规则
  2. findLink=re.compile(r'<a href="(.*?)">') #创建正则表达式,表示规则(字符串模式)
  3. #爬取网页
  4. def getData(baseurl):
  5. datalist=[]
  6. for i in range(0,1): #调用获取页面信息的函数,10次
  7. url=baseurl + str(i*25)
  8. html=askURL(url) #保存获取到的网页源码
  9. #2.逐一解析数据
  10. soup=BeautifulSoup(html,"html.parser")
  11. for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,形成列表
  12. #print(item) #测试:查看电影item全部信息
  13. data=[] #保存一部电影的全部信息
  14. item=str(item)
  15. #影片详情的链接
  16. link=re.findall(findLink,item)[0] #re库用来通过正则表达式查找指定的字符串,[0]表示如果有两个,只要第一个
  17. print(link)
  18. return datalist

https://movie.douban.com/subject/1292052/
https://movie.douban.com/subject/1291546/
。。。。。。。。
https://movie.douban.com/subject/1291560/
https://movie.douban.com/subject/3319755/

截断整出一个电影的item信息,把需求的东西都提取出来,之后加循环就行了

  1. #爬取网页
  2. def getData(baseurl):
  3. datalist=[]
  4. for i in range(0,1): #调用获取页面信息的函数,10次
  5. url=baseurl + str(i*25)
  6. html=askURL(url) #保存获取到的网页源码
  7. #2.逐一解析数据
  8. soup=BeautifulSoup(html,"html.parser")
  9. for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,形成列表
  10. #print(item) #测试:查看电影item全部信息
  11. data=[] #保存一部电影的全部信息
  12. item=str(item)
  13. print(item)
  14. break
  15. #影片详情的链接
  16. link=re.findall(findLink,item)[0] #re库用来通过正则表达式查找指定的字符串,[0]表示如果有两个,只要第一个
  17. print(link)
  18. return datalist

保存到一个html文档里面进行对比

  1. <div class="item">
  2. <div class="pic">
  3. <em class="">1</em>
  4. <a href="https://movie.douban.com/subject/1292052/">
  5. <img alt="肖申克的救赎" class="" src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg" width="100"/>
  6. </a>
  7. </div>
  8. <div class="info">
  9. <div class="hd">
  10. <a class="" href="https://movie.douban.com/subject/1292052/">
  11. <span class="title">肖申克的救赎</span>
  12. <span class="title"> / The Shawshank Redemption</span>
  13. <span class="other"> / 月黑高飞(港) / 刺激1995(台)</span>
  14. </a>
  15. <span class="playable">[可播放]</span>
  16. </div>
  17. <div class="bd">
  18. <p class="">
  19. 导演: 弗兰克·德拉邦特 Frank Darabont 主演: 蒂姆·罗宾斯 Tim Robbins /...<br/>
  20. 1994 / 美国 / 犯罪 剧情
  21. </p>
  22. <div class="star">
  23. <span class="rating5-t"></span>
  24. <span class="rating_num" property="v:average">9.7</span>
  25. <span content="10.0" property="v:best"></span>
  26. <span>2523850人评价</span>
  27. </div>
  28. <p class="quote">
  29. <span class="inq">希望让人自由。</span>
  30. </p>
  31. </div>
  32. </div>
  33. </div>

 将相关需要提取的东西转为正则表达式,并设置为全局变量

  1. #影片详情的链接的规则
  2. findLink=re.compile(r'<a href="(.*?)">') #创建正则表达式,表示规则(字符串模式)
  3. #影片图片
  4. findImgSrc=re.compile(r'<img.*src="(.*?)"',re.S) #re.S让换行符包含在字符中
  5. #影片片名
  6. findTitle=re.compile(r'<span class="title">(.*)</span>')
  7. #影片评分
  8. findRating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
  9. #找到评价人数
  10. findJudge=re.compile(r'<span>(\d*)人评价</span>')
  11. #找到概况
  12. findInq=re.compile(r'<span class="inq">(.*)</span>')
  13. #找到影片的相关内容
  14. findBd=re.compile(r'<p class="">(.*?)</p>',re.S)

把电影的相关信息保存到datalist里面

  1. #影片详情的链接
  2. link=re.findall(findLink,item)[0] #re库用来通过正则表达式查找指定的字符串,[0]表示如果有两个,只要第一个
  3. data.append(link) #列表添加链接
  4. imgSrc=re.findall(findImgSrc,item)[0]
  5. data.append(imgSrc) #列表添加图片
  6. titles=re.findall(findTitle,item) #片名可能只有一个中文名,没有外文名
  7. if(len(titles)==2):
  8. ctitle=titles[0] #添加中文名
  9. data.append(ctitle)
  10. otitle=titles[1].replace("/","") #去掉无关的符号
  11. data.append(otitle) #添加外国名
  12. else:
  13. data.append(titles[0])
  14. data.append(' ') #外国名留空
  15. rating=re.findall(findRating,item)[0]
  16. data.append(rating) #添加评分
  17. judgeNum=re.findall(findJudge,item)[0]
  18. data.append(judgeNum) #添加评价人数
  19. inq=re.findall(findInq,item)[0]
  20. if len(inq)!=0:
  21. inq=inq[0].replace("。","") #去掉句号
  22. data.append(inq) #添加概述
  23. else:
  24. data.append(" ") #留空
  25. bd=re.findall(findBd,item)
  26. bd=re.sub('<br(\s+)?/>(\s+)?'," ",bd) #去掉<br/>
  27. bd=re.sub('/'," ",bd) #去掉/
  28. data.append(bd.strip()) #去掉前后的空格
  29. datalist.append(data) #把处理好的一部电影信息放入datalist

全代码

  1. #-*- coding: utf-8 -*-
  2. from bs4 import BeautifulSoup #网页解析,获取数据
  3. import re #正则表达式,进行文字匹配
  4. import urllib.request,urllib.error #制定URL,获取网络数据
  5. import xlwt #进行excel操作
  6. import sqlite3 #进行SQLite数据库操作
  7. def main():
  8. baseurl="https://movie.douban.com/top250?start="
  9. #1.爬取网页
  10. datalist=getData(baseurl)
  11. savepath=".\\豆瓣电影Top250.xls" #当前文件夹下
  12. #3.保存数据
  13. #saveData(savepath)
  14. askURL("https://movie.douban.com/top250?start=")
  15. #影片详情的链接的规则
  16. findLink=re.compile(r'<a href="(.*?)">') #创建正则表达式,表示规则(字符串模式)
  17. #影片图片
  18. findImgSrc=re.compile(r'<img.*src="(.*?)"',re.S) #re.S让换行符包含在字符中
  19. #影片片名
  20. findTitle=re.compile(r'<span class="title">(.*)</span>')
  21. #影片评分
  22. findRating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
  23. #找到评价人数
  24. findJudge=re.compile(r'<span>(\d*)人评价</span>')
  25. #找到概况
  26. findInq=re.compile(r'<span class="inq">(.*)</span>')
  27. #找到影片的相关内容
  28. findBd=re.compile(r'<p class="">(.*?)</p>',re.S)
  29. #爬取网页
  30. def getData(baseurl):
  31. datalist=[]
  32. for i in range(0,1): #调用获取页面信息的函数,10次
  33. url=baseurl + str(i*25)
  34. html=askURL(url) #保存获取到的网页源码
  35. #2.逐一解析数据
  36. soup=BeautifulSoup(html,"html.parser")
  37. for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,形成列表
  38. #print(item) #测试:查看电影item全部信息
  39. data=[] #保存一部电影的全部信息
  40. item=str(item)
  41. #影片详情的链接
  42. link=re.findall(findLink,item)[0] #re库用来通过正则表达式查找指定的字符串,[0]表示如果有两个,只要第一个
  43. data.append(link) #列表添加链接
  44. imgSrc=re.findall(findImgSrc,item)[0]
  45. data.append(imgSrc) #列表添加图片
  46. titles=re.findall(findTitle,item) #片名可能只有一个中文名,没有外文名
  47. if(len(titles)==2):
  48. ctitle=titles[0] #添加中文名
  49. data.append(ctitle)
  50. otitle=titles[1].replace("/","") #去掉无关的符号
  51. data.append(otitle) #添加外国名
  52. else:
  53. data.append(titles[0])
  54. data.append(' ') #外国名留空
  55. rating=re.findall(findRating,item)[0]
  56. data.append(rating) #添加评分
  57. judgeNum=re.findall(findJudge,item)[0]
  58. data.append(judgeNum) #添加评价人数
  59. inq=re.findall(findInq,item)
  60. if len(inq)!=0:
  61. inq=inq[0].replace("。","") #去掉句号
  62. data.append(inq) #添加概述
  63. else:
  64. data.append(" ") #留空
  65. bd=re.findall(findBd,item)[0]
  66. bd=re.sub('<br(\s+)?/>(\s+)?'," ",bd) #去掉<br/>
  67. bd=re.sub('/'," ",bd) #去掉/
  68. data.append(bd.strip()) #去掉前后的空格
  69. datalist.append(data) #把处理好的一部电影信息放入datalist
  70. print (datalist)
  71. return datalist
  72. #得到一个指定URL的网页内容
  73. def askURL(url):
  74. #模拟浏览器头部信息,向豆瓣服务器发送信息
  75. head={"User-Agent":" Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"}
  76. #用户代理,表示告诉豆瓣服务器,我们是什么类型的机器,浏览器(本质上是高速浏览器,我们可以接受什么水平的信息)
  77. request=urllib.request.Request(url,headers=head)
  78. html=""
  79. try:
  80. response=urllib.request.urlopen(request)
  81. html=response.read().decode("utf-8")
  82. #print(html)
  83. except urllib.error.URLError as e: #捕获错误
  84. if hasattr(e,"code"):
  85. print(e.code) #打印错误代码
  86. if hasattr(e,"reason"):
  87. print(e.reason) #打印错误原因
  88. return html
  89. #保存数据
  90. def saveData(savepath):
  91. print("save.....")
  92. if __name__ == "__main__": #当程序执行时
  93. #调用函数
  94. main()

3.4保存数据

3.4.1Excel表存储

利用python库xlwt将抽取的数据datalist写入Excel表格

  1. 以utf-8编码创建一个Excel对象
  2. 创建一个Sheet表
  3. 往单元格写入内容
  4. 保存表格

用几行python代码写入xls表格

  1. import xlwt
  2. workbook=xlwt.Workbook(encoding="utf-8") #创建workbook对象
  3. worksheet=workbook.add_sheet('sheet1') #创建工作表
  4. worksheet.write(0,0,'hello') #写入数据,第一个参数表示行,第二个参数表示列,第三个参数内容
  5. workbook.save('student.xls') #保存文件

 例子:在xls表格写入99乘法表

  1. import xlwt
  2. workbook=xlwt.Workbook(encoding="utf-8") #创建workbook对象
  3. worksheet=workbook.add_sheet('sheet1') #创建工作表
  4. for i in range(1,10): #行
  5. for j in range(1,i+1): #列
  6. worksheet.write(i-1,j-1,"%d * %d = %d"%(i,j,i*j))
  7. workbook.save('99.xls') #保存文件

 保存数据:Top250

  1. #保存数据
  2. def saveData(datalist,savepath):
  3. print("save.....")
  4. book=xlwt.Workbook(encoding="utf-8",style_compression=0) #样式压缩效果
  5. sheet=book.add_sheet('豆瓣电影TOP250',cell_overwrite_ok=True) #单元格可以覆盖
  6. col=("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息") #元组
  7. for i in range(0,8):
  8. sheet.write(0,i,col[i])
  9. for i in range(0,250):
  10. print("第%d条"%i)
  11. data=datalist[i]
  12. for j in range(0,8):
  13. sheet.write(i+1,j,data[j]) #数据
  14. book.save('doubanTop250.xls') #保存

Message=list index out of range 错误

将inq=re.findall(findInq,item)[0]

改为inq=re.findall(findInq,item)

xls表格保存豆瓣Top250的全代码

  1. #-*- coding: utf-8 -*-
  2. from bs4 import BeautifulSoup #网页解析,获取数据
  3. import re #正则表达式,进行文字匹配
  4. import urllib.request,urllib.error #制定URL,获取网络数据
  5. import xlwt #进行excel操作
  6. import sqlite3 #进行SQLite数据库操作
  7. def main():
  8. baseurl="https://movie.douban.com/top250?start="
  9. #1.爬取网页
  10. datalist=getData(baseurl)
  11. savepath=".\\豆瓣电影Top250.xls" #当前文件夹下
  12. #3.保存数据
  13. saveData(datalist,savepath)
  14. askURL("https://movie.douban.com/top250?start=")
  15. #影片详情的链接的规则
  16. findLink=re.compile(r'<a href="(.*?)">') #创建正则表达式,表示规则(字符串模式)
  17. #影片图片
  18. findImgSrc=re.compile(r'<img.*src="(.*?)"',re.S) #re.S让换行符包含在字符中
  19. #影片片名
  20. findTitle=re.compile(r'<span class="title">(.*)</span>')
  21. #影片评分
  22. findRating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
  23. #找到评价人数
  24. findJudge=re.compile(r'<span>(\d*)人评价</span>')
  25. #找到概况
  26. findInq=re.compile(r'<span class="inq">(.*)</span>')
  27. #找到影片的相关内容
  28. findBd=re.compile(r'<p class="">(.*?)</p>',re.S)
  29. #爬取网页
  30. def getData(baseurl):
  31. datalist=[]
  32. for i in range(0,10): #调用获取页面信息的函数,10次
  33. url=baseurl + str(i*25)
  34. html=askURL(url) #保存获取到的网页源码
  35. #2.逐一解析数据
  36. soup=BeautifulSoup(html,"html.parser")
  37. for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,形成列表
  38. #print(item) #测试:查看电影item全部信息
  39. data=[] #保存一部电影的全部信息
  40. item=str(item)
  41. #影片详情的链接
  42. link=re.findall(findLink,item)[0] #re库用来通过正则表达式查找指定的字符串,[0]表示如果有两个,只要第一个
  43. data.append(link) #列表添加链接
  44. imgSrc=re.findall(findImgSrc,item)[0]
  45. data.append(imgSrc) #列表添加图片
  46. titles=re.findall(findTitle,item) #片名可能只有一个中文名,没有外文名
  47. if(len(titles)==2):
  48. ctitle=titles[0] #添加中文名
  49. data.append(ctitle)
  50. otitle=titles[1].replace("/","") #去掉无关的符号
  51. data.append(otitle) #添加外国名
  52. else:
  53. data.append(titles[0])
  54. data.append(' ') #外国名留空
  55. rating=re.findall(findRating,item)[0]
  56. data.append(rating) #添加评分
  57. judgeNum=re.findall(findJudge,item)[0]
  58. data.append(judgeNum) #添加评价人数
  59. inq=re.findall(findInq,item)
  60. if len(inq)!=0:
  61. inq=inq[0].replace("。","") #去掉句号
  62. data.append(inq) #添加概述
  63. else:
  64. data.append(" ") #留空
  65. bd=re.findall(findBd,item)[0]
  66. bd=re.sub('<br(\s+)?/>(\s+)?'," ",bd) #去掉<br/>
  67. bd=re.sub('/'," ",bd) #去掉/
  68. data.append(bd.strip()) #去掉前后的空格
  69. datalist.append(data) #把处理好的一部电影信息放入datalist
  70. #print (datalist)
  71. return datalist
  72. #得到一个指定URL的网页内容
  73. def askURL(url):
  74. #模拟浏览器头部信息,向豆瓣服务器发送信息
  75. head={"User-Agent":" Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"}
  76. #用户代理,表示告诉豆瓣服务器,我们是什么类型的机器,浏览器(本质上是高速浏览器,我们可以接受什么水平的信息)
  77. request=urllib.request.Request(url,headers=head)
  78. html=""
  79. try:
  80. response=urllib.request.urlopen(request)
  81. html=response.read().decode("utf-8")
  82. #print(html)
  83. except urllib.error.URLError as e: #捕获错误
  84. if hasattr(e,"code"):
  85. print(e.code) #打印错误代码
  86. if hasattr(e,"reason"):
  87. print(e.reason) #打印错误原因
  88. return html
  89. #保存数据
  90. def saveData(datalist,savepath):
  91. print("save.....")
  92. book=xlwt.Workbook(encoding="utf-8",style_compression=0) #样式压缩效果
  93. sheet=book.add_sheet('豆瓣电影TOP250',cell_overwrite_ok=True) #单元格可以覆盖
  94. col=("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息") #元组
  95. for i in range(0,8):
  96. sheet.write(0,i,col[i])
  97. for i in range(0,250):
  98. print("第%d条"%i)
  99. data=datalist[i]
  100. for j in range(0,8):
  101. sheet.write(i+1,j,data[j]) #数据
  102. book.save('doubanTop250.xls') #保存
  103. if __name__ == "__main__": #当程序执行时
  104. #调用函数
  105. main()
  106. print("爬去完毕")

补充SQLite相关知识

SQLite相关知识_aiqq136的博客-CSDN博客sqlite是python3后支持的简单数据库打开或创建数据库import sqlite3conn=sqlite3.connect(“test.db”) #打开或创建数据库print(“Opened database successfully”)pycharm通过database查看SQLite数据库SQLite建表格式import sqlite3conn=sqlite3.connect(“test.db”) #打开或创建数据库prin..https://blog.csdn.net/aiqq136/article/details/122478368

保存数据到SQLite

主函数修改

  1. def main():
  2. baseurl="https://movie.douban.com/top250?start="
  3. #1.爬取网页
  4. datalist=getData(baseurl)
  5. #savepath=".\\豆瓣电影Top250.xls" #当前文件夹下
  6. dbpath="movie.db"
  7. #3.保存数据
  8. #saveData(datalist,savepath)
  9. saveData2DB(datalist,dbpath)
  10. #askURL("https://movie.douban.com/top250?start=")

数据库保存数据

  1. #数据库保存数据
  2. def saveData2DB(datalist,dbpath):
  3. print("...")

创建数据库

  1. #创建数据库
  2. def init_db(dbpath):
  3. sql='''
  4. create table movie250
  5. (
  6. id integer primary key autoincrement,
  7. info_link text,
  8. pic_link text,
  9. cname varchar,
  10. ename varchar,
  11. score numeric,
  12. rated numeric,
  13. instroduction text,
  14. info text
  15. )
  16. ''' #创建数据表
  17. conn=sqlite3.connect(dbpath)
  18. cursor=conn.cursor()
  19. cursor.execute(sql)
  20. conn.commit()
  21. conn.close()
  22. if __name__ == "__main__": #当程序执行时
  23. #调用函数
  24. #main()
  25. init_db("movietest.db")
  26. print("爬取完毕")

数据库保存数据

  1. #数据库保存数据
  2. def saveData2DB(datalist,dbpath):
  3. print("saving....")
  4. init_db(dbpath)
  5. conn=sqlite3.connect(dbpath) #链接数据库
  6. cur=conn.cursor() #游标
  7. #print(datalist)
  8. for data in datalist:
  9. for index in range(len(data)):
  10. if index==4 or index==5:
  11. continue
  12. data[index]='"'+data[index]+'"'
  13. sql='''
  14. insert into movie250(
  15. info_link,pic_link,cname,ename,score,rated,instroduction,info)
  16. values(%s)'''%",".join(data)
  17. print(sql)
  18. #cur.execute(sql)
  19. #conn.commit()
  20. cur.close()
  21. conn.close()
  22. print("save done....")

全代码

  1. #-*- coding: utf-8 -*-
  2. from bs4 import BeautifulSoup #网页解析,获取数据
  3. import re #正则表达式,进行文字匹配
  4. import urllib.request,urllib.error #制定URL,获取网络数据
  5. import xlwt #进行excel操作
  6. import sqlite3 #进行SQLite数据库操作
  7. def main():
  8. baseurl="https://movie.douban.com/top250?start="
  9. #1.爬取网页
  10. datalist=getData(baseurl)
  11. #savepath=".\\豆瓣电影Top250.xls" #当前文件夹下
  12. dbpath="movie.db"
  13. #3.保存数据
  14. #saveData(datalist,savepath)
  15. saveData2DB(datalist,dbpath)
  16. #askURL("https://movie.douban.com/top250?start=")
  17. #影片详情的链接的规则
  18. findLink=re.compile(r'<a href="(.*?)">') #创建正则表达式,表示规则(字符串模式)
  19. #影片图片
  20. findImgSrc=re.compile(r'<img.*src="(.*?)"',re.S) #re.S让换行符包含在字符中
  21. #影片片名
  22. findTitle=re.compile(r'<span class="title">(.*)</span>')
  23. #影片评分
  24. findRating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
  25. #找到评价人数
  26. findJudge=re.compile(r'<span>(\d*)人评价</span>')
  27. #找到概况
  28. findInq=re.compile(r'<span class="inq">(.*)</span>')
  29. #找到影片的相关内容
  30. findBd=re.compile(r'<p class="">(.*?)</p>',re.S)
  31. #爬取网页
  32. def getData(baseurl):
  33. datalist=[]
  34. for i in range(0,10): #调用获取页面信息的函数,10次
  35. url=baseurl + str(i*25)
  36. html=askURL(url) #保存获取到的网页源码
  37. #2.逐一解析数据
  38. soup=BeautifulSoup(html,"html.parser")
  39. for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,形成列表
  40. #print(item) #测试:查看电影item全部信息
  41. data=[] #保存一部电影的全部信息
  42. item=str(item)
  43. #影片详情的链接
  44. link=re.findall(findLink,item)[0] #re库用来通过正则表达式查找指定的字符串,[0]表示如果有两个,只要第一个
  45. data.append(link) #列表添加链接
  46. imgSrc=re.findall(findImgSrc,item)[0]
  47. data.append(imgSrc) #列表添加图片
  48. titles=re.findall(findTitle,item) #片名可能只有一个中文名,没有外文名
  49. if(len(titles)==2):
  50. ctitle=titles[0] #添加中文名
  51. data.append(ctitle)
  52. otitle=titles[1].replace("/","") #去掉无关的符号
  53. data.append(otitle) #添加外国名
  54. else:
  55. data.append(titles[0])
  56. data.append(' ') #外国名留空
  57. rating=re.findall(findRating,item)[0]
  58. data.append(rating) #添加评分
  59. judgeNum=re.findall(findJudge,item)[0]
  60. data.append(judgeNum) #添加评价人数
  61. inq=re.findall(findInq,item)
  62. if len(inq)!=0:
  63. inq=inq[0].replace("。","") #去掉句号
  64. data.append(inq) #添加概述
  65. else:
  66. data.append(" ") #留空
  67. bd=re.findall(findBd,item)[0]
  68. bd=re.sub('<br(\s+)?/>(\s+)?'," ",bd) #去掉<br/>
  69. bd=re.sub('/'," ",bd) #去掉/
  70. data.append(bd.strip()) #去掉前后的空格
  71. datalist.append(data) #把处理好的一部电影信息放入datalist
  72. #print (datalist)
  73. return datalist
  74. #得到一个指定URL的网页内容
  75. def askURL(url):
  76. #模拟浏览器头部信息,向豆瓣服务器发送信息
  77. head={"User-Agent":" Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"}
  78. #用户代理,表示告诉豆瓣服务器,我们是什么类型的机器,浏览器(本质上是高速浏览器,我们可以接受什么水平的信息)
  79. request=urllib.request.Request(url,headers=head)
  80. html=""
  81. try:
  82. response=urllib.request.urlopen(request)
  83. html=response.read().decode("utf-8")
  84. #print(html)
  85. except urllib.error.URLError as e: #捕获错误
  86. if hasattr(e,"code"):
  87. print(e.code) #打印错误代码
  88. if hasattr(e,"reason"):
  89. print(e.reason) #打印错误原因
  90. return html
  91. #保存数据
  92. def saveData(datalist,savepath):
  93. print("save.....")
  94. book=xlwt.Workbook(encoding="utf-8",style_compression=0) #样式压缩效果
  95. sheet=book.add_sheet('豆瓣电影TOP250',cell_overwrite_ok=True) #单元格可以覆盖
  96. col=("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息") #元组
  97. for i in range(0,8):
  98. sheet.write(0,i,col[i])
  99. for i in range(0,250):
  100. print("第%d条"%i)
  101. data=datalist[i]
  102. for j in range(0,8):
  103. sheet.write(i+1,j,data[j]) #数据
  104. book.save('doubanTop250.xls') #保存
  105. #数据库保存数据
  106. def saveData2DB(datalist,dbpath):
  107. print("saving....")
  108. init_db(dbpath)
  109. conn=sqlite3.connect(dbpath) #链接数据库
  110. cur=conn.cursor() #游标
  111. for data in datalist:
  112. for index in range(len(data)):
  113. if index==4 or index==5:
  114. continue
  115. data[index]='"'+data[index]+'"'
  116. sql='''
  117. insert into movie250(
  118. info_link,pic_link,cname,ename,score,rated,instroduction,info)
  119. values(%s)'''%",".join(data)
  120. #print(sql)
  121. cur.execute(sql)
  122. conn.commit()
  123. cur.close()
  124. conn.close()
  125. print("save done....")
  126. #创建数据库
  127. def init_db(dbpath):
  128. sql='''
  129. create table movie250
  130. (
  131. id integer primary key autoincrement,
  132. info_link text,
  133. pic_link text,
  134. cname varchar,
  135. ename varchar,
  136. score numeric,
  137. rated numeric,
  138. instroduction text,
  139. info text
  140. )
  141. ''' #创建数据表
  142. conn=sqlite3.connect(dbpath)
  143. cursor=conn.cursor()
  144. cursor.execute(sql)
  145. conn.commit()
  146. conn.close()
  147. if __name__ == "__main__": #当程序执行时
  148. #调用函数
  149. main()
  150. print("爬取完毕")

爬取成功并存到数据库中