爬取豆瓣网电影Top250数据完整代码(Python+Pymysql+Flask+echarts)


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'')      # 影片的链接
  9 findImgSrc = re.compile(r'',re.S)    # 影片的背景图链接
 10 findtitle = re.compile(r'(.*?)')   #影片名称
 11 findRating = re.compile(r'(.*)')  #评分
 12 findJudge = re.compile(r'(\d*)人评价')       #评价人数
 13 findInq = re.compile(r'(.*)')  # 概述
 14 findBd = re.compile(r'

(.*?)

',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"): # 找到
标签的 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('(\s+)?'," ",bd) #去掉
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