爬取豆瓣电影及可视化

一、主题式网络爬虫设计方案

1.主题式网络爬虫名称:豆瓣电影数据评分

2.主题式网络爬虫爬取的内容:豆瓣电影的榜单数字、名称、评星、评分、评论数量。

3.设计方案概述:

实现思路:使用requests爬取网页,然后实现数据解析,借助pandas将数据写出到Excel;把数据进行清洗处理;然后对清洗的数据进行分析,进行相关的可视化;最后,将这些代码进行整理。

技术难点:网页内容繁杂,刚开始接触,不太好懂;对数据的解析有些漫长;可视化中,数据不匹配。

二、主题页面的结构特征分析

1.打开开发者工具,查找我所需的内容,以及它所在的标签;在 div class="item" 中查找。

2.进行页面解析

3分析节点

   

三、网络爬虫程序设计

1.数据爬取与采集

#获取页面
import requests
from bs4 import BeautifulSoup
import pandas as pd
# 构造分页数字列表
page_indexs = range(0, 250, 25)
list(page_indexs)
def download_all_htmls():
    """
    下载所有列表页面的HTML,用于后续的分析
    """
    htmls = []
    for idx in page_indexs:
        url = f"https://movie.douban.com/top250?start={idx}&filter="
        print("craw html:", url)
        r = requests.get(url,
                        headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"})
        if r.status_code != 200:
            raise Exception("error")
        htmls.append(r.text)
    return htmls
htmls = download_all_htmls()
htmls[0]
def parse_single_html(html):
    """
    解析单个HTML,得到数据
    @return list({"link", "title", [label]})
    """
    soup = BeautifulSoup(html, 'html.parser')
    article_items = (
        soup.find("div", class_="article")
            .find("ol", class_="grid_view")
            .find_all("div", class_="item")
    )
    datas = []
    for article_item in article_items:
        rank = article_item.find("div", class_="pic").find("em").get_text()
        info = article_item.find("div", class_="info")
        title = info.find("div", class_="hd").find("span", class_="title").get_text()
        stars = (
            info.find("div", class_="bd")
                .find("div", class_="star")
                .find_all("span")
        )
        rating_star = stars[0]["class"][0]
        rating_num = stars[1].get_text()
        comments = stars[3].get_text()
        
        datas.append({
            "rank":rank,
            "title":title,
            "rating_star":rating_star.replace("rating","").replace("-t",""),
            "rating_num":rating_num,
            "comments":comments.replace("人评价", "")
        })
    return datas

import pprint
pprint.pprint(parse_single_html(htmls[0]))
# 执行所有的HTML页面的解析
all_datas = []
for html in htmls:
    all_datas.extend(parse_single_html(html))
    
all_datas
len(all_datas)
df = pd.DataFrame(all_datas)
df.to_excel("豆瓣电影TOP250.xlsx")

#保存成功

2.对数据进行清洗和处理

#数据读取

 df= pd.read_excel('D:\python\\豆瓣电影TOP250.xlsx',encoding='gbk')

print(df.head(10)) 

#删除无效行列

 df.drop('Unnamed: 0',axis=1,inplace=True)

print(df.head(10)) 

#重复值处理

 print(df.duplicated()) 

#异常值处理

 print(df.describe()) 

4.数据分析与可视化

#导入各库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sklearn
import seaborn as sns
from sklearn.linear_model import LinearRegression
from mpl_toolkits.mplot3d import Axes3D

(1)

#绘制垂直柱状图
x = df.title[:6]
y = df.comments[:6]#由于数据太多,只列了前几个

plt.bar(x,y,color="b")

plt.xlabel("title")

plt.ylabel("comments")

plt.title('影片与评价人数柱状图')

plt.show()

(2)

#散点图
x = df.rating_num
y = df.comments

plt.scatter(x,y,color="g",label="散点")

plt.xlabel("rating_num")

plt.ylabel("comments")

plt.title('评分与评价人数散点图')

plt.show()

(3)

#绘制3D散点图

fig=plt.figure()

ax=Axes3D(fig)

x=df.rating_num

y=df.rating_star

z=df.comments

ax.scatter(x,y,z)

ax.set_xlabel('x')

ax.set_ylabel('y')

ax.set_zlabel('z')

plt.show()
#由于评价人数过多,所以数据比较贴近

(4)

#绘制折线图

x = df.title[:6]

y = df.comments[:6]
#探究前几影片评价人数的关系

plt.scatter(x,y)

plt.xlabel("title")

plt.ylabel("comments")

plt.plot(x,y,'y-*')

plt.title('影片与评价人数折线图')
plt.show()

(5)

#绘制盒图
x = df.rating_num

y = df.comments

sns.boxplot(x='rating_num',y='comments',data=df)

(6)

 #绘制直方图

sns.distplot(df['rating_num']) 

(7)

 #绘制单变量小提琴图 sns.violinplot(df['rating_num']) 

(8)

#绘制热力图

data=df.pivot('comments','rating_num','rating_star')

sns.heatmap(data)

5.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变量之间的回归方程

df= pd.read_excel('D:\python\\豆瓣电影TOP250.xlsx',encoding='gbk')

df.drop('title',axis=1,inplace=True)
#由于title里的文字无法进行数据分析,所以进行删除

X=df.drop("rating_num",axis=1)

predict_model=LinearRegression()

predict_model.fit(X,df['rating_num'])#训练模型

print("回归系数为:",predict_model.coef_)#判断相关性

#呈现回归图
sns.regplot(df.comments ,df.rating_num)

7.将以上各部分的代码汇总,附上完整程序代码

import requests
from bs4 import BeautifulSoup
import pandas as pd
# 构造分页数字列表
page_indexs = range(0, 250, 25)
list(page_indexs)
def download_all_htmls():
    """
    下载所有列表页面的HTML,用于后续的分析
    """
    htmls = []
    for idx in page_indexs:
        url = f"https://movie.douban.com/top250?start={idx}&filter="
        print("craw html:", url)
        r = requests.get(url,
                        headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"})
        if r.status_code != 200:
            raise Exception("error")
        htmls.append(r.text)
    return htmls
htmls = download_all_htmls()
htmls[0]
def parse_single_html(html):
    """
    解析单个HTML,得到数据
    @return list({"link", "title", [label]})
    """
    soup = BeautifulSoup(html, 'html.parser')
    article_items = (
        soup.find("div", class_="article")
            .find("ol", class_="grid_view")
            .find_all("div", class_="item")
    )
    datas = []
    for article_item in article_items:
        rank = article_item.find("div", class_="pic").find("em").get_text()
        info = article_item.find("div", class_="info")
        title = info.find("div", class_="hd").find("span", class_="title").get_text()
        stars = (
            info.find("div", class_="bd")
                .find("div", class_="star")
                .find_all("span")
        )
        rating_star = stars[0]["class"][0]
        rating_num = stars[1].get_text()
        comments = stars[3].get_text()
        
        datas.append({
            "rank":rank,
            "title":title,
            "rating_star":rating_star.replace("rating","").replace("-t",""),
            "rating_num":rating_num,
            "comments":comments.replace("人评价", "")
        })
    return datas

import pprint
pprint.pprint(parse_single_html(htmls[0]))
# 执行所有的HTML页面的解析
all_datas = []
for html in htmls:
    all_datas.extend(parse_single_html(html))
    
all_datas
len(all_datas)
df = pd.DataFrame(all_datas)
df.to_excel("豆瓣电影TOP250.xlsx")


#数据清洗
import pandas as pd
df
= pd.read_excel('D:\python\\豆瓣电影TOP250.xlsx',encoding='gbk') print(df.head(10))
#删除无效行列

df.drop('Unnamed: 0',axis=1,inplace=True) print(df.head(10))
#重复值处理

print(df.duplicated())
#异常值处理

print(df.describe()) #数据分析与可视化

#导入所需的库 import numpy as np import pandas as pd import matplotlib.pyplot as plt import sklearn import seaborn as sns from sklearn.linear_model import LinearRegression #绘制垂直柱状图 x = df.title[:6] y = df.comments[:6]#由于数据太多,只列了前几个 plt.bar(x,y,color="b") plt.xlabel("title") plt.ylabel("comments") plt.title('影片与评价人数柱状图') plt.show() #散点图 x = df.rating_num y = df.comments plt.scatter(x,y,color="g",label="散点") plt.xlabel("rating_num") plt.ylabel("comments") plt.title('评分与评价人数散点图') plt.show() #绘制3D散点图 fig=plt.figure() ax=Axes3D(fig) x=df.rating_num y=df.rating_star z=df.comments ax.scatter(x,y,z) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') #由于评价人数过多,所以数据比较贴近 plt.show() #绘制折线图 x = df.title[:6] y = df.comments[:6] #探究前几影片评价人数的关系 plt.scatter(x,y) plt.xlabel("title") plt.ylabel("comments") plt.plot(x,y,'y-*') plt.title('影片与评价人数折线图') plt.show() #绘制盒图 x = df.rating_num y = df.comments sns.boxplot(x='rating_num',y='comments',data=df) #绘制直方图 sns.distplot(df['rating_num']) #绘制单变量小提琴图 sns.violinplot(df['rating_num']) #绘制热力图 data=df.pivot('comments','rating_num','rating_star') sns.heatmap(data) df= pd.read_excel('D:\python\\豆瓣电影TOP250.xlsx',encoding='gbk') df.drop('title',axis=1,inplace=True) #由于title里的文字无法进行数据分析,所以进行删除 X=df.drop("rating_num",axis=1) predict_model=LinearRegression() predict_model.fit(X,df['rating_num'])#训练模型 print("回归系数为:",predict_model.coef_)#判断相关性 #呈现回归图 sns.regplot(df.comments ,df.rating_num)

四、结论

1.结论:经过这次的作业,我知晓了电影行业评价好的,基本热议度高,但也有一些不一定。我学习到了,每次输出结果报错,可以上网搜一下它错的原因,这样就会对自己的代码错误有了更清晰的认识。不要怕有错误,及时修改就好。

2.小结:对于这次的作业,作为一个纯纯的新手来说,真的不容易。我也花了不少时间去研究它,慢慢的学习,发现python也挺不简单的。不过,我也收获不少,希望以后的学习中可以有所进步。

猜你喜欢

转载自www.cnblogs.com/n4ll/p/12748687.html