对于豆瓣电影的Tp250条movies数据的爬取+可视化我们分为两个步骤:
1、数据的爬取;

2、数据的可视化。

对于一个爬虫数据,我们简单就几行就可以爬取到一个完整网页:

import requests
head={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
}
response = requests.get('https://www.baidu.com',headers=head)

html = response.text
print(html)

爬取结果(当然,有些网站能防爬,可能是乱码,也可能是因为ajax的原因爬取不完整):
在这里插入图片描述

一、数据爬取

那么我们怎么爬取完整的豆瓣电影并可视化呢?首先我们定义一个spider.py文件对电影数据进行爬取。spider.py文件内容我将按步骤划分(完整就是按步骤合起来,都归属于spider.py):

1、这是要用到的库文件
from bs4 import BeautifulSoup  //用于解析拿到的网页
import re  //用于匹配正则项
import urllib.request,urllib.error  //用于配置访问网页路由,即想爬取网页地址
import pymysql   //连接Mysql
2、接着我们根据豆瓣网页的HTML代码设置正则表达式

设置正则表达式的原因是提取你想要的部分,例如你想要电影名称、网址、图片、访问人数,都可以用正则表达式去提取。我这里简单拿出了想要的代码,如果不懂这个哪里来的,可以查看豆瓣Top250条电影的网页,按F12即可。

<img width="100" alt="肖申克的救赎" src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" class=""> 
#下面的正则表达式根据这个html代码进行提取
................................正则表达开始式......................................................................
#影片详情链接
findLink = re.compile(r'<a href="(.*?)">')  #创建正则表达式对象,表示匹配规则
#影片图片
#<img width="100" alt="肖申克的救赎" src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" class=""> 
#下面的正则表达式根据这个html代码进行提取
findImgSrc = re.compile(r'<img.*src="(.*?)"',re.S) #让换行符包含在字符中
#影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')
#影片评分
findRating =re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
#影片评价人数
findJudge = re.compile(r'<span>(\d*)人评价</span>')
#影片概况
findInq = re.compile(r'<span class="inq">(.*)</span>')
#影片相关内容
findBd = re.compile(r'<p class="">(.*?)</p>',re.S)
3、接着开始爬取数据设置

1、设置请求头,因为不设置的话,就会检测出是爬虫代码,无法爬取。请求头哪里来呢,访问豆瓣电影,F12就可以拿到。
在这里插入图片描述
这里用到了urllib的知识,有些用request、selenuim等

................................请求头设置......................................................................
def askURL(url):
    head={
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
    }
    request=urllib.request.Request(url=url,headers=head)  //这里是设置请求头信息
    html = ""   //用于存放待会爬取到的网页
    try:
        response = urllib.request.urlopen(request)  //请求去访问URL地址
        html = response.read().decode("utf-8")  //保存爬到网页的html代码
        # print(html)
    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)
    return html
4、下一步就是加上正则提取想要数据,如果不知道每句话干嘛,可以print打印结果就明白了
................................数据开始爬取......................................................................
def getData(baseurl):
    datalist = []
    # 解析数据
    for i in range(0,10):
        url = baseurl + str(i*25)
        html = askURL(url)  //这里调用我们前面定义的askURL函数
        soup = BeautifulSoup(html,"html.parser")  //这里需要用html.parser解析一下爬到的网页Html代码
        #########  上面三句,已经爬到整个网页数据了,下面for循环用来提取想要信息 ##############
        for item in soup.find_all('div',class_="item"):
            # print(item) 测试:查看电影item全部信息
            data = []
            item = str(item)
            #影片详情链接
            link = re.findall(findLink,item)[0]
            data.append(link)

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

            #影片标题
            titles = re.findall(findTitle,item)
            if(len(titles)==2):   #如果有中英文标题,则分开存储
                ctitle = titles[0]
                data.append(ctitle)
                otitle = titles[1].replace("/","") #去掉无关符号 /The Shawshank Redemption
                data.append(otitle)
            else:
                data.append(titles[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('<br(\s+)?/>(\s+)?'," ",bd)  #去掉<br>
            bd = re.sub('/'," ",bd)  #替换
            data.append(bd.strip())  #去掉前后空格

            datalist.append(data) #把处理好的一部电影信息放入datalist中
    return datalist
5、有了数据,接下来就用Mysql保存数据
...............................建立数据表并保存数据......................................................................
def init_db():  #建表操作
    sql='''
        create table movie250(
        id int primary key auto_increment,
        info_link text,
        pic_link text,
        cname varchar(100),
        ename varchar(100),
        score double,
        rated double,
        introduce text,
        info text
        )
    '''
    # 建立连接
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456',db='spider',charset='utf8')
    # 建立游标,python, 必须有一个游标对象, 用来给数据库发送sql语句, 并执行的.
    cursor = conn.cursor()
    cursor.execute(sql)
    # 4. 关闭游标
    cursor.close()
    # 5. 关闭连接
    conn.close()

def saveToMysql(dataList):
    init_db()
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456',db='spider',charset='utf8')  
    cursor = 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,introduce,info)
                    values(%s)'''%",".join(data)
        # print(sql)
        cursor.execute(sql)
        conn.commit()
    cursor.close()
    conn.close()
6、这里我简单提一下PyCharm与Mysql连接步骤,看红框位置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在url的3306后面再加就能成功连接了

?serverTimezone=GMT

函数都定义好了,那就开始执行:

def main():
    baseurl="https://movie.douban.com/top250?start="
    # 爬取网页
    datalist = getData(baseurl)
    saveToMysql(datalist)

if __name__=="__main__":
    main()
    print("爬取完毕")
7、爬取结果

在这里插入图片描述

还 与 数 据 库 没 连 接 成 功 的 可 以 认 真 看 看 我 的 表 名 和 数 据 库 名 。 \color{red}{还与数据库没连接成功的可以认真看看我的表名和数据库名。 }

二、数据可视化

这里我运用到了比较简单的Flask框架,用到上面spider.py爬到的数据。由于html文件比较多,我就简单放一个app.py,完整项目代码,文件夹附上。
app.py

from flask import Flask,render_template
import pymysql
app = Flask(__name__)


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

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

@app.route('/movie')
def movie():

    dataList = []
    # 建立连接
    conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='123456',db='spider',charset='utf8')
    # 建立游标,python, 必须有一个游标对象, 用来给数据库发送sql语句, 并执行的.
    cursor = conn.cursor()
    # 4. 关闭游标
    sql = 'select * from movie250'
    result = cursor.execute(sql)
    data = cursor.fetchall()  #查询得到的结果是元组((1,...),(2,...))
    for item in data:
        dataList.append(item)
    cursor.close()
    # 5. 关闭连接
    conn.close()
    return render_template("movie.html",movies=dataList)

@app.route('/score')
def score():
    score =[] #评分
    num = [] #每个评分对应的电影数量
    # 建立连接
    conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='123456',db='spider',charset='utf8')
    # 建立游标,python, 必须有一个游标对象, 用来给数据库发送sql语句, 并执行的.
    cursor = conn.cursor()
    # 4. 关闭游标
    sql = 'select score,count(score) from movie250 group by score'
    cursor.execute(sql)
    data = cursor.fetchall()  #查询得到的结果是元组((1,...),(2,...))
    for item in data:
        score.append(str(item[0]))
        num.append(item[1])
    cursor.close()
    # 5. 关闭连接
    conn.close()

    return render_template("score.html",score=score,num=num)

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

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


if __name__ == '__main__':
    app.run()
1、可视化结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
文中与数据库的连接别忘记修改成自己的喔

conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='123456',db='spider',charset='utf8')
2、完整代码附上

https://pan.baidu.com/s/1OVCghBiZZa1-sFt-sl_KBQ .
提取码:9ezs

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐