爬取豆瓣电影前20

 

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

1.爬虫名称:爬取豆瓣电影前20

2.爬虫爬取的内容:爬取豆瓣电影前20数据。 

3.网络爬虫设计方案概述:
实现思路:通过访问网页源代码,使用soup.find_all正则表达爬取数据,对数据进行保存数据,再对数据进行清洗和处理,数据分析与可视化处理。
技术难点:经常爬不到所需要找的标签内容。

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

1.主题页面的结构与特征分析:主题页面访问网址为:'https://movie.douban.com/top250'

特征分析:电影名标签分布在span class="title"中,评分标签分布在span class="rating_num"中,电影介绍标签分布在span class="inq"中。

2.Htmls页面解析:

 

 

 

 

3.节点(标签)查找方法与遍历方法:通过遍历标签查找所需内容。

三、网络爬虫程序设计

1.数据爬取与采集:

 1 from bs4 import BeautifulSoup
 2 import pandas as pd
 3 from sklearn.linear_model import LinearRegression
 4 import seaborn as sns
 5 import numpy as np
 6 import matplotlib.pyplot as plt
 7 import matplotlib
 8 from scipy.optimize import leastsq
 9 
10 #定义爬虫函数
11 def get_html(url):
12     headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'}#伪装爬虫
13     resp = requests.get(url, headers = headers) 
14     return resp.text
15 
16 url = 'https://movie.douban.com/top250'
17 html = get_html(url)
18 soup = BeautifulSoup(html, 'html.parser')#正则表达
19 
20 
21 a = soup.find_all('div', class_='hd')
22 #电影名
23 name = [] 
24 for i in a:
25     name.append(i.a.span.text)
26 
27 #评分    
28 score = soup.find_all('span', class_='rating_num')
29 
30 #介绍
31 introduce = soup.find_all('span', class_='inq')
32     
33 lt = []
34 #遍历前20
35 num = 20
36 for i in range(num):
37     lt.append([i+1,name[i], score[i].string, introduce[i].string])
38 df = pd.DataFrame(lt,columns = ['排名', '电影名', '评分', '介绍']) 
39 df.to_csv('豆瓣电影前20数据.csv') #保存文件,数据持久化

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

1 #读取csv文件
2 df = pd.DataFrame(pd.read_csv('豆瓣电影前20数据.csv'))
3 df.head()

#删除无效列与行
df.drop('介绍', axis=1, inplace = True)
df.head()

#检查是否有重复值
df.duplicated()

#空值处理
df.isnull().sum()#返回0,表示没有空值

#缺失值处理
df[df.isnull().values==True]#返回无缺失值

#用describe()命令显示描述性统计指标
df.describe()

 

 3.数据分析与可视化

#算出评分回归系数
X = df.drop("电影名",axis=1)
predict_model = LinearRegression()
predict_model.fit(X,df['评分'])
print("回归系数为:",predict_model.coef_)

#绘制排名与评分的回归图
plt.rcParams['font.sans-serif']=['STSong']
sns.regplot(df.排名,df.评分)

# 绘制垂直柱状图
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
plt.bar(df.排名, df.评分, label="排名与评分柱状图")
plt.show()

# 绘制散点图
def Scatter_point():
    
    plt.scatter(df.排名, df.评分, color='blue', s=25, marker="o")
    plt.xlabel("排名")
    plt.ylabel("评分")
    plt.title("排名与评分散点图")
    plt.show()
Scatter_point()

#绘制折线图
def point1():  
    x = df['排名']
    y = df['评分']
    plt.xlabel('排名')
    plt.ylabel('评分')
    plt.plot(x,y)
    plt.scatter(x,y)
    plt.title("绘制排名与评分折线图")
    plt.show()    
point1()

 

#绘制排名与评分箱体图
def point2():
    plt.figure(figsize=(10, 6))
    plt.title('绘制排名与评分箱体图')
    sns.boxplot(x='排名',y='评分', data=df)
point2()

#绘制其它分布图
sns.jointplot(x="排名",y='评分',data = df, kind='kde', color='r')

sns.jointplot(x="排名",y='评分',data = df)

sns.jointplot(x="排名",y='评分',data = df, kind='reg')

sns.jointplot(x="排名",y='评分',data = df, kind='hex')

 

 

 

 

 

 

 

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

#绘制一元一次回归方程
def main(): 
    colnames = ["排名", "电影名", "评分", "介绍"]
    df = pd.read_csv('豆瓣电影前20数据.csv',skiprows=1,names=colnames)
    X = df.排名
    Y = df.评分
    def func(p, x):
        k, b = p
        return k * x + b
    def error_func(p, x, y):
        return func(p,x)-y
    p0 = [0,0] 
    Para = leastsq(error_func, p0, args = (X, Y))
    k, b = Para[0]
    print("k=",k,"b=",b) 
    plt.figure(figsize=(10,6))
    plt.scatter(X,Y,color="green",label=u"评分分布",linewidth=2)
    x=np.linspace(0,30,20)
    y=k*x+b
    plt.plot(x,y,color="red",label=u"回归方程直线",linewidth=2) 
    plt.title("电影排名和评分一元一次回归方程图")
    plt.xlabel('排名')
    plt.ylabel('评分')
    plt.legend() 
    plt.show()  
main()

#绘制一元二次回归方程
def point1_2():
    colnames = ["排名", "电影名", "评分", "介绍"]
    df = pd.read_csv('豆瓣电影数据.csv',skiprows=1,names=colnames)
    X = df.排名
    Y = df.评分
    def func(p,x):
        a,b,c=p
        return a*x*x+b*x+c
    def error_func(p,x,y):
        return func(p,x)-y
    p0=[0,0,0]
    Para=leastsq(error_func,p0,args=(X,Y))
    a,b,c=Para[0]   
    plt.figure(figsize=(10,6)) 
    plt.scatter(X,Y,color="green",label=u"评分分布",linewidth=2)
    x=np.linspace(0,30,20)
    y=a*x*x+b*x+c
    plt.plot(x,y,color="red",label=u"拟合直线",linewidth=2) 
    plt.title("电影排名和评分一元二次回归方程关系图")
    plt.legend() 
    plt.show()
point1_2()

5.数据持久化

1 df.to_csv('豆瓣电影前20数据.csv') #保存文件,数据持久化

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

  1 ########################开始编程######################
  2 import requests
  3 from bs4 import BeautifulSoup
  4 import pandas as pd
  5 from sklearn.linear_model import LinearRegression
  6 import seaborn as sns
  7 import numpy as np
  8 import matplotlib.pyplot as plt
  9 import matplotlib
 10 from scipy.optimize import leastsq
 11 
 12 #定义爬虫函数
 13 def get_html(url):
 14     headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'}#伪装爬虫
 15     resp = requests.get(url, headers = headers) 
 16     return resp.text
 17 
 18 url = 'https://movie.douban.com/top250'
 19 html = get_html(url)
 20 soup = BeautifulSoup(html, 'html.parser')#正则表达
 21 
 22 
 23 a = soup.find_all('div', class_='hd')
 24 #电影名
 25 name = [] 
 26 for i in a:
 27     name.append(i.a.span.text)
 28 
 29 #评分    
 30 score = soup.find_all('span', class_='rating_num')
 31 
 32 #介绍
 33 introduce = soup.find_all('span', class_='inq')
 34 
 35 lt=[]    
 36 #遍历前20
 37 num = 20
 38 for i in range(num):
 39     lt.append([i+1,name[i], score[i].string, introduce[i].string])
 40 df = pd.DataFrame(lt,columns = ['排名', '电影名', '评分', '介绍']) 
 41 df.to_csv('豆瓣电影前20数据.csv') #保存文件,数据持久化
 42 
 43 #读取csv文件
 44 df = pd.DataFrame(pd.read_csv('豆瓣电影前20数据.csv'))
 45 df.head()
 46 
 47 #删除无效列与行
 48 df.drop('介绍', axis=1, inplace = True)
 49 df.head()
 50 
 51 #检查是否有重复值
 52 df.duplicated()
 53 
 54 #空值处理
 55 df.isnull().sum()#返回0,表示没有空值
 56 
 57 #缺失值处理
 58 df[df.isnull().values==True]#返回无缺失值
 59 
 60 #用describe()命令显示描述性统计指标
 61 df.describe()
 62 
 63 #算出评分回归系数
 64 X = df.drop("电影名",axis=1)
 65 predict_model = LinearRegression()
 66 predict_model.fit(X,df['评分'])
 67 print("回归系数为:",predict_model.coef_)
 68 
 69 #绘制排名与评分的回归图
 70 plt.rcParams['font.sans-serif']=['STSong']
 71 sns.regplot(df.排名,df.评分)
 72 
 73 # 绘制垂直柱状图
 74 plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
 75 plt.bar(df.排名, df.评分, label="排名与评分柱状图")
 76 plt.show()
 77 
 78 # 绘制散点图
 79 def Scatter_point():
 80     
 81     plt.scatter(df.排名, df.评分, color='blue', s=25, marker="o")
 82     plt.xlabel("排名")
 83     plt.ylabel("评分")
 84     plt.title("排名与评分散点图")
 85     plt.show()
 86 Scatter_point()
 87 
 88 #绘制折线图
 89 def point1():  
 90     x = df['排名']
 91     y = df['评分']
 92     plt.xlabel('排名')
 93     plt.ylabel('评分')
 94     plt.plot(x,y)
 95     plt.scatter(x,y)
 96     plt.title("绘制排名与评分折线图")
 97     plt.show()    
 98 point1()
 99 
100 #绘制排名与评分箱体图
101 def point2():
102     plt.figure(figsize=(10, 6))
103     plt.title('绘制排名与评分箱体图')
104     sns.boxplot(x='排名',y='评分', data=df)
105 point2()
106 
107 #绘制其它分布图
108 sns.jointplot(x="排名",y='评分',data = df, kind='kde', color='r')
109 
110 sns.jointplot(x="排名",y='评分',data = df)
111 
112 sns.jointplot(x="排名",y='评分',data = df, kind='reg')
113 
114 sns.jointplot(x="排名",y='评分',data = df, kind='hex')
115 
116 #绘制一元一次回归方程
117 def main(): 
118     colnames = ["排名", "电影名", "评分", "介绍"]
119     df = pd.read_csv('豆瓣电影前20数据.csv',skiprows=1,names=colnames)
120     X = df.排名
121     Y = df.评分
122     def func(p, x):
123         k, b = p
124         return k * x + b
125     def error_func(p, x, y):
126         return func(p,x)-y
127     p0 = [0,0] 
128     Para = leastsq(error_func, p0, args = (X, Y))
129     k, b = Para[0]
130     print("k=",k,"b=",b) 
131     plt.figure(figsize=(10,6))
132     plt.scatter(X,Y,color="green",label=u"评分分布",linewidth=2)
133     x=np.linspace(0,30,20)
134     y=k*x+b
135     plt.plot(x,y,color="red",label=u"回归方程直线",linewidth=2) 
136     plt.title("电影排名和评分一元一次回归方程图")
137     plt.xlabel('排名')
138     plt.ylabel('评分')
139     plt.legend() 
140     plt.show()  
141 main()
142 #绘制一元二次回归方程
143 def point1_2():
144     colnames = ["排名", "电影名", "评分", "介绍"]
145     df = pd.read_csv('豆瓣电影数据.csv',skiprows=1,names=colnames)
146     X = df.排名
147     Y = df.评分
148     def func(p,x):
149         a,b,c=p
150         return a*x*x+b*x+c
151     def error_func(p,x,y):
152         return func(p,x)-y
153     p0=[0,0,0]
154     Para=leastsq(error_func,p0,args=(X,Y))
155     a,b,c=Para[0]   
156     plt.figure(figsize=(10,6)) 
157     plt.scatter(X,Y,color="green",label=u"评分分布",linewidth=2)
158     x=np.linspace(0,30,20)
159     y=a*x*x+b*x+c
160     plt.plot(x,y,color="red",label=u"拟合直线",linewidth=2) 
161     plt.title("电影排名和评分一元二次回归方程关系图")
162     plt.legend() 
163     plt.show()
164 point1_2()
165 ##########################编程结束######################

四、结论

1.经过对主题数据的分析与可视化,可以得到哪些结论?

经过对主题数据的分析与可视化,可以让我更直观的了解到表面上所呈现的数据,更能理解数据
2.对本次程序设计任务完成的情况做一个简单的小结。

在这次作业中,通过不断的对代码进行修改,让我加深了对python的掌握,通过这次作业,让我补足了我很多不足,让我收获良多

posted @ 2020-09-29 13:29  崔欣宇  阅读(410)  评论(0编辑  收藏  举报