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