爬虫练习——豆瓣电影信息爬取及数据可视化

最近自学了简单的爬虫项目,简单记录下自己的小白学习路径。

本次爬取的是豆瓣电影TOP250数据,主要用到beautifulsoup、re、urllib库、SQLite包,数据可视化方面主要用到flask框架、echarts和wordcloud等,搭建简单的数据可视化网站。

话不多说,下面开始。

一、数据爬取阶段

1、需求分析

这次爬取的豆瓣电影TOP250信息数据,包括名称、豆瓣评分、评价人数、电影概况以及电影链接等,具体网址为movie.douban.com/top250

爬虫练习——豆瓣电影信息爬取及数据可视化

2、准备工作

(1)首先要分析页面URL,250条电影数据每页有25个,共十页的数据。

爬虫练习——豆瓣电影信息爬取及数据可视化

第一页的网址为movie.douban.com/top250?start=0&filter=,,观察规律可以发现该页网络地址为https://movie.douban.com/top250?start=(该页页数-1)*25,第一页是0,第二页是25,第三页是50,以此类推(后面的&filter=为过滤筛选项,可以忽略)。

(2)接下来要分析页面,找到所需数据在网页信息中的位置。在页面点击F12进入开发者模式,点击相关信息即可获得对应的网页位置。

爬虫练习——豆瓣电影信息爬取及数据可视化

3、获取数据

通过HTTP库向网页发起请求,请求可包含额外的header等信息(如浏览器信息基本User-Agent、Cookie等),如果服务器能正常响应,会得到一个response,这便是所要获取的页面内容。

首先导入需要的库

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

爬取网页前设定基本的数据,厘清整个框架。

def main():
    baseurl = "https://movie.douban.com/top250?start="
    #1.爬取网页,用getDate()函数
    datalist = getDate(baseurl)
    #2.逐一解析数据(可与1同步进行)
    #3.保存数据,用saveData2DB()函数
    dbpath = "movie.bd"             #数据库保存路径
    saveData2DB(datalist,dbpath)    #存储到database中的方法
if __name__ == "__main__":          #当程序执行时
 #调用函数
    main()
    print("爬取完毕!")

搭好框架后,在其中加以分析,首先要获取网页的内容。

# 得到指定一个url网页内容
def askURL(url):
    head = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36"
    }           # 模拟浏览器头部信息,向豆瓣服务器发送消息(发送请求时对浏览器做的伪装)
    # 用户代理:表示告诉豆瓣浏览器,我们是什么类型的机器,实质上是告诉浏览器,我们可以接收什么水平的文件内容

    requst = urllib.request.Request(url,headers=head)       # 用封装的信息访问
    html = ""
    try:
        response = urllib.request.urlopen(requst)
        html = response.read().decode("utf-8")
    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)

    return html

然后对网页信息进行逐页爬取

# 爬取网页
def getDate(baseurl):
    datalist = []

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

4、解析内容

爬虫后得到的内容可能是HTML、JSON等格式,可以用BeautifulSoup定位特定标签位置、正则表达式找到具体内容的方式进行解析。在解析前建议先学习下正则表达式的一些知识,详情请自行百度。

找到各个所需信息的网页特征,用正则表达式创建规则。

# 影片详情链接的规则
findLink = re.compile(r'')         #创建正则表达式对象,表示规则(字符串的模式)
# 影片图片
findImgSrc = re.compile(r'<img.*src="(.*?)"',re.S)      #re.S表示忽略换行的情况,让换行符包含在字符中
# 影片的片名
findTitle = re.compile(r'(.*)')
# 影片的评分
findRating = re.compile(r'(.*)')
# 找到评价人数
findJudge = re.compile(r'(d*)人评价')
# 找到概况
findInq = re.compile(r'(.*)')
# 找到影片的相关内容
findBd = re.compile(r'

(.*?)

'
,re.S)

再对相关对象进行提取(这里的解析与网页爬取是一起进行的)。

# 爬取网页
def getDate(baseurl):
    datalist = []

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

    # 逐一进行解析
        soup = BeautifulSoup(html,"html.parser")
        for item in soup.find_all('div',class_="item"):     #查找符合要求的字符串,形成列表
            # print(item)   #测试查看电影item全部信息
            data = []           #保存一部电影的所有信息
            item = str(item)

            # 获取影片详情的链接
            link = re.findall(findLink,item)[0]     #re库用来通过正则表达式查找指定的字符串(0表示只要一个)
            data.append(link)                       #添加链接

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

            title = re.findall(findTitle,item)      #片名可能只有一个中文名,没有外文名
            if(len(title) == 2):
                ctitiles = title[0]                 #添加中文名
                data.append(ctitiles)
                otitles = title[1].replace("/","")      #去掉无关的符号    #添加外国名
                data.append(otitles)
            else:
                data.append(title[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('
(s+)?'
," ",str(bd)) #去掉
bd = re.sub('/'," ",str(bd)) #替换/ data.append(bd.strip()) #去掉前后的空格 datalist.append(data) #把处理好的一部电影信息放入datalist return datalist

5、保存数据

用SQLite将解析过的数据保存到数据库,首先要创建数据库(涉及到SQL语句,建议提前学习一点基础知识)。

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,
    introduction text,
    info text
    )'''
    conn = sqlite3.connect(dbpath)
    cursor = conn.cursor()
    cursor.execute(sql)
    conn.commit()
    conn.close()

再将数据保存到数据库中。

def saveData2DB(datalist,dbpath):
    #init_db(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,ename,score,rated,introduction,info)
            values(%s)'''%",".join(data)
        print(sql)
        cur.execute(sql)
        conn.commit()
    cur.close()
    conn.close()

数据爬取工作就完成啦!

爬虫练习——豆瓣电影信息爬取及数据可视化

看到数据库里爬到的数据无比有成就感哈哈哈~

二、数据可视化阶段

利用flask框架,改造创立一个简单的可视化网址,包含首页、电影、评分、词云以及团队五个部分,效果如下:

爬虫练习——豆瓣电影信息爬取及数据可视化

flask框架的核心是请求的路由转发(Werkzeug完成)和界面的渲染和网页拼装(jinja2完成),非常灵活,适合像我这样的小白。

1、前期准备

首先要获取网页模板,我这边直接下载了群里的模板资源

新建flask项目,将之前爬到的数据库movie.db粘贴到新项目中。新建文件会自动出现基础代码,完成hello world网站搭建的基础工作。

爬虫练习——豆瓣电影信息爬取及数据可视化

将网页复制到到templates文件夹下里,获得网站整个的html信息。再将网页的assets文件夹整体复制到到pycharm的static文件夹里,获得网站静态文件信息。

2、网页制作

按F12通过对比原网页信息,来修改HTML代码,以此来获取自己需要的效果。举个栗子

想要修改导航栏的相关信息,将Home、About US等信息改为首页、电影、评分等信息,通过在原网站查找定位

爬虫练习——豆瓣电影信息爬取及数据可视化

再对HTML信息查找,并进行相关更改

爬虫练习——豆瓣电影信息爬取及数据可视化

由此就可对整个网页进行自由的删改重组了,具体过程太长就不赘述了。

3、绘制图表

绘制图表运用了Echarts,Echarts是一个图表的开源项目,可以免费使用,也很容易上手,适合小白。建议在官网自行学习相关的文档,对运用有基础的了解。

爬虫练习——豆瓣电影信息爬取及数据可视化

这里选用了简单的柱形图,在网页直接进行编辑修改。

爬虫练习——豆瓣电影信息爬取及数据可视化

粘贴到HTML代码的对应位置即可,效果如下。

爬虫练习——豆瓣电影信息爬取及数据可视化

4、词云的制作

词云的制作需要jieba库、matplotlib库、Wordcloud库、Image库、numpy库以及sqlite3库。首先制作词云

import jieba                                #分词
from matplotlib import pyplot as plt        #绘图,数据可视化
from wordcloud import WordCloud, STOPWORDS  # 词云
from PIL import Image                       #图片处理
import numpy as np                          #矩阵运算
import _sqlite3                             #数据库


#准备词云所需的文字(词)
con = _sqlite3.connect("D:/dai ma/pycharm/douban_flask/movie.bd")
cur = con.cursor()
sql = 'select introduction from movie250'
data = cur.execute(sql)
text = ""
for item in data:
    text = text + item[0]
print(text)
cur.close()
con.close()

#分词
cut = jieba.cut(text)
string = ' '.join(cut)
print(len(string))

#绘图
img = Image.open(r'D:dai mapycharmdouban_flaskstaticassetsimgtree.jpg')       #打开遮罩图片
img_array = np.array(img)       #将图片转化为数组
#设置屏蔽词
exclude={'我们','你们','我','你','是','的','了','和','都',
          }
wc = WordCloud(
    background_color='white',
    mask=img_array,
    stopwords=exclude,
    font_path="Deng.ttf"        #字体在C盘windows下的fonts文件夹下——属性复制名字.ttf文件
)
wc.generate_from_text(string)

#绘制图片
fig = plt.figure(1)
plt.imshow(wc)
plt.axis('off')     #是否显示坐标轴

#plt.show()          #显示生成的词云图片

#输出词云图片到文件
plt.savefig(r'D:dai mapycharmdouban_flaskstaticassetsimgwordclud.jpg',dpi=500)

最后的效果如下

爬虫练习——豆瓣电影信息爬取及数据可视化

将制作好的词云保存,写入HTML对应的位置即可。

5、分别制作好首页、电影、评分、词云、团队等几个部分后,要进行各个页面的调用制作

from flask import Flask,render_template
import sqlite3

app = Flask(__name__)

@app.route('/')
def index():
    return render_template("index.html")

@app.route('/index')
def home():
    return render_template("index.html")
    # return index()

@app.route('/movie')
def movie():
    datalist = []
    con = sqlite3.connect("D:/dai ma/pycharm/douban_flask/movie.bd")
    cur = con.cursor()
    sql = "select * from movie250"
    data = cur.execute(sql)
    for item in data:
        datalist.append(item)
    cur.close()
    con.close()
    return render_template("movie.html",movies = datalist)

@app.route('/score')
def score():
    score = []      #评分
    num = []        #计数
    con = sqlite3.connect("D:/dai ma/pycharm/douban_flask/movie.bd")
    cur = con.cursor()
    sql = "select score,count(score) from movie250 group by score"
    data = cur.execute(sql)
    for item in data:
        score.append(item[0])
        num.append(item[1])
    cur.close()
    con.close()
    return render_template("score.html",score = score,num = num)

@app.route('/word')
def word():
    return render_template("word.html")

@app.route('/team')
def team():
    return render_template("team.html")

if __name__ == '__main__':
    app.run(debug=True)

然后就获得了一个简单的数据可视化网页啦~

最终的效果如下

完结~

作为初学者,我知道还有许多值得改进的地方,也有好多还需要学习的地方,后续如果还有改进的话会继续来记笔记的,顺便感谢B站李巍老师,讲的真的简单易懂,虽然我本身学习过不少python和sql的基础知识,但是没有应用和产出,只会让我学的越来越没劲,这次能爬出来数据真的特有成就感,顺便也学习了flask框架的一些知识,最重要的是重新燃起了学习的欲望,在被各种error打击后重拾了的信心。

奉上一时脑抽加上的彩蛋:

爬虫练习——豆瓣电影信息爬取及数据可视化

给自己打气,继续加油学习!早日转行成功!

  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
afiregame
  • 本文由 发表于 2021年12月11日21:42:49
  • 转载请务必保留本文链接:https://www.afiregame.com/zixun/6002/
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: