首页 > 技术文章 > 爬取豆瓣网电影Top250数据完整代码(Python+Pymysql+Flask+echarts)

lcc0 2022-03-04 20:27 原文

spider.py:爬取数据代码

  1 import urllib.request
  2 import urllib.error
  3 from bs4 import BeautifulSoup
  4 import re
  5 import pymysql
  6 
  7 # 希望得到的网页数据的规范
  8 findLink = re.compile(r'<a href="(.*?)">')      # 影片的链接
  9 findImgSrc = re.compile(r'<img.*src="(.*?)"',re.S)    # 影片的背景图链接
 10 findtitle = re.compile(r'<span class="title">(.*?)</span>')   #影片名称
 11 findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')  #评分
 12 findJudge = re.compile(r'<span>(\d*)人评价</span>')       #评价人数
 13 findInq = re.compile(r'<span class="inq">(.*)</span>')  # 概述
 14 findBd = re.compile(r'<p class="">(.*?)</p>',re.S)      # 影片详细信息
 15 
 16 def askURL(url):
 17     head = {
 18             "User-Agent":"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0"
 19 
 20     }                          # 用户代理,告诉网站我们是(模拟成的)什么机器,浏览器
 21     request = urllib.request.Request(url,headers=head)   # 模拟一个浏览器请求
 22     html = ""             # 定义一个空html 来准备接收 response
 23     try:
 24         response = urllib.request.urlopen(request)   # 回应的网页
 25         html = response.read().decode("utf-8")       # 用utf-8读取网页
 26         #print(html)
 27     except urllib.error.URLError as e:    # 如果出错,打印出网页返回的code码(404,418等等)
 28         if hasattr(e, "code"):
 29             print(e.code)
 30         if hasattr(e, "reason"):          # 如果出错,有出错的原因,打印处出错原因
 31             print(e.reason)
 32     return html
 33 
 34 
 35 def getData(baseurl):                     # 获取数据的函数
 36     datalist = []
 37     # 解析数据
 38     for i in range(0,1,1):   # 10页
 39         url = baseurl + str(i*25)   # 25是第二页
 40         html = askURL(url)     # 得到一页的网页数据
 41         soup = BeautifulSoup(html,"html.parser")  # 用html解析器来解析网页
 42         for item in soup.find_all('div',class_="item"):  # 找到<div>标签的 class=“item的内容,item:即每个影片内容
 43             # print(item) 测试:查看电影item全部信息
 44             data = []
 45             item = str(item)
 46             #影片详情链接
 47             link = re.findall(findLink,item)[0]    # 正则匹配
 48             data.append(link)
 49 
 50             #影片图片
 51             imgSrc = re.findall(findImgSrc,item)[0]
 52             data.append(imgSrc)
 53 
 54             #影片标题
 55             titles = re.findall(findtitle,item)
 56             if(len(titles)==2):   #如果有中英文标题,则分开存储  而英文标题在中文标题的后面:title[1]
 57                 ctitle = titles[0]
 58                 data.append(ctitle)
 59                 otitle = titles[1].replace("/","").replace("\xa0","") #去掉无关符号 /The Shawshank Redemption
 60                 data.append(otitle)
 61             else:
 62                 data.append(titles[0])
 63                 data.append(' ')
 64 
 65             #影片评分
 66             rating = re.findall(findRating,item)[0]
 67             data.append(rating)
 68             #影片评价人数
 69             judgeNum = re.findall(findJudge,item)[0]
 70             data.append(judgeNum)
 71 
 72             #影片概述
 73             inq = re.findall(findInq,item)
 74             if len(inq) != 0:             # 不为空
 75                 inq = inq[0].replace("","")  #用空格代替句号,从而去掉句号
 76                 data.append(inq)
 77             else:
 78                 data.append(" ")  #如果为空的留空
 79 
 80             # 影片相关内容
 81             bd = re.findall(findBd,item)[0]
 82             bd = re.sub('<br(\s+)?/>(\s+)?'," ",bd)  #去掉</br>
 83             bd = re.sub('/'," ",bd)  #用空格替换/
 84             data.append(bd.strip())  #去掉前后空格
 85 
 86             datalist.append(data) #把处理好的一部电影信息放入datalist中
 87             print(datalist)
 88     return datalist
 89 
 90 
 91 
 92 def init_db():
 93     sql = '''
 94         create table movieTop250(
 95         id int primary key auto_increment,
 96         info_link text,
 97         pic_link text,
 98         cname varchar(100),
 99         ename varchar(100),
100         score double,
101         rated double,
102         introduce text,
103         info text  
104         )
105     '''
106     con = pymysql.connect(host="127.0.0.1",port=3306,user="root",passwd=" ",db="spider")
107     cursor = con.cursor()             # user为你本地数据库的用户名,passwd为你本地数据库的密码,db为创建的数据库
108     cursor.execute(sql)               # 数据库db自己提前创建好
109     con.commit()
110     print("创表成功!")
111     cursor.close()
112     con.close()
113 
114 def saveToMysql(datalist):
115     init_db()
116     con = pymysql.connect(host="127.0.0.1",port=3306,user="root",passwd=" ",db="spider")
117     cursor = con.cursor()
118     for data in datalist:  # 250行,  data:每部电影的信息
119         for index in range(len(data)):  # index:每行的8列 列标识,即每部电影的8列信息(影片链接,图片链接,名称,评分,评分人数,概述,影片信息)
120             print(data)
121             if index == 4 or index == 5:  # 第5,6列是数字,可以不加” “
122                 continue
123                 data[index] = '"'+data[index]+'"'   # 加“ ”,将每列改为含有“ ”的字符串,方便sql语句操作字符串
124 
125         sql = '''
126         insert into movieTop250(info_link,pic_link,cname,ename,score,rated,introduce,info)
127         values(%s)'''%",".join(data)     # 每部电影的信息用,隔开,形成8列
128         cursor.execute(sql)              # 注:sql语句应该在第一个for循环下,循环250次,插入250行数据
129         con.commit()
130     print("数据存储成功!")
131     cursor.close()
132     con.close()
133 
134 def main():
135     baseurl="https://movie.douban.com/top250?start="
136     # 爬取网页
137     datalist = getData(baseurl)
138     # 保存数据
139     saveToMysql(datalist)
140 
141 if __name__ == '__main__':
142     main()
143     print("爬取成功!")

 

app.py:数据可视化代码

 1 from flask import Flask,render_template
 2 import pymysql
 3 from wsgiref.simple_server import make_server
 4 app = Flask(__name__)
 5 
 6 
 7 @app.route('/')
 8 def index():
 9     return render_template("index.html")
10 
11 @app.route('/index')
12 def index2():
13     return render_template("index.html")
14     # return index() 也可
15 
16 @app.route('/movie')
17 def movie():
18 
19     dataList = []
20     # 建立连接
21     conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='',db='spider',charset='utf8')
22     # 建立游标,python, 必须有一个游标对象, 用来给数据库发送sql语句, 并执行的.
23     cursor = conn.cursor()
24     # 4. 关闭游标
25     sql = 'select * from movie250'
26     result = cursor.execute(sql)
27     data = cursor.fetchall()  #查询得到的结果是元组((1,...),(2,...))
28     for item in data:
29         dataList.append(item)
30     cursor.close()
31     # 5. 关闭连接
32     conn.close()
33     return render_template("movie.html",movies=dataList)
34 
35 @app.route('/score')
36 def score():
37     score =[] #评分
38     num = [] #每个评分对应的电影数量
39     # 建立连接
40     conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='',db='spider',charset='utf8')
41     # 建立游标,python, 必须有一个游标对象, 用来给数据库发送sql语句, 并执行的.
42     cursor = conn.cursor()
43     # 4. 关闭游标
44     sql = 'select score,count(score) from movie250 group by score'
45     cursor.execute(sql)
46     data = cursor.fetchall()  #查询得到的结果是元组((1,...),(2,...))
47     for item in data:
48         score.append(str(item[0]))
49         num.append(item[1])
50     cursor.close()
51     # 5. 关闭连接
52     conn.close()
53 
54     return render_template("score.html",score=score,num=num)
55 
56 @app.route('/team')
57 def team():
58     return render_template("team.html")
59 
60 @app.route('/word')
61 def word():
62     return render_template("word.html")
63 
64 
65 if __name__ == '__main__':
66     server = make_server('127.0.0.1', 5001, app)
67     server.serve_forever()
68     app.run()

 

详细代码文件和可视化的网页模板:

百度网盘:

链接:https://pan.baidu.com/s/1KRjFL_XuavyDkh-gw1n2wQ?pwd=eztb
提取码:eztb

 

如该文章能对你有所帮助,请帮忙点个推荐和关注!谢谢!0.0

推荐阅读