爬取豆瓣电影评分top250数据分析

一、主题式网络爬虫设计方案(15分)
1.主题式网络爬虫名称

豆瓣电影TOP250数据分析
2.主题式网络爬虫爬取的内容与数据特征分析

分析豆瓣电影电影的相关类容
3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)

思路:网页内容的选取  对所选取网页进行html解析 ,单击鼠标右键查看网页源代码,找到关键内容的索引标签,对标签进行分析理解,提取关键字眼。导入第三方库,再将所爬取到的内容进行数据清洗.分析,绘制图形方程,以及可视化处理。

难点:对于数据的处理有较高的技术要求

二、主题页面的结构特征分析(15分)
1.主题页面的结构及特征分析

打开爬取网站https://movie.douban.com  下面内容得

肖申克的救赎

导演: 弗兰克·德拉邦特 Frank Darabont   主演: 蒂姆·罗宾斯 Tim Robbins /...
1994 / 美国 / 犯罪 剧情

9.7 2149682人评价

希望让人自由。

   

# <span property="v:itemreviewed">  肖申克的救赎 The Shawshank Redemption</span>
# <a href="/celebrity/1047973/" rel="v:directedBy">  弗兰克·德拉邦特</a>
# <a href="/celebrity/1054521/" rel="v:starring">  蒂姆·罗宾斯</a>


2.Htmls页面解析

三、网络爬虫程序设计(60分)
爬虫程序主体要包括以下各部分,要附源代码及较详细注释,并在每部分程序后面提供输出结果的截图。
1.数据爬取与采集(20)

复制代码
import requests
from bs4 import BeautifulSoup
import re
import pandas
from matplotlib import pyplot as plt
import numpy as np
import scipy as sp
import pandas as pd
from matplotlib import pyplot as plt
import matplotlib
import seaborn as sns
from scipy.optimize import leastsq

headers = {
    'Host':'movie.douban.com',
    'Origin':'movie.douban.com',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36',
}
base_url = 'https://movie.douban.com/top250?start={}&filter='





response = requests.get('https://movie.douban.com/top250?start=0&filter=', headers = headers, allow_redirects=False)
if response.status_code == 200:
    # print(response.text)
    pass

pattern1 = re.compile('<div.*?class="item">.*?<div.*?class="pic">.*?<a.*?href="(.*?)">', re.S) # 去掉所有换行符,并用正则表达式去匹配每一个页面的具体电影
urls = re.findall(pattern1, response.text)

directors = []# 导演名

names = []# 电影名称

stars = []# 主演人物

countrys = []# 电影的拍摄地

languages = []# 电影语言种类

typs = []# 电影类型

sorces = []# 评分

# <span property="v:itemreviewed">  肖申克的救赎 The Shawshank Redemption</span>
# <a href="/celebrity/1047973/" rel="v:directedBy">  弗兰克·德拉邦特</a>
# <a href="/celebrity/1054521/" rel="v:starring">  c蒂姆·罗宾斯</a>
def base_urls(base_url):
    urls = []

    # for i in range(0, 250, 25):
    #     true_url = base_url.format(i)
    #     print(true_url)
    for i in range(0, 50, 25):
        true_url = base_url.format(i)

        response = requests.get(true_url, headers=headers, allow_redirects=False)
        if response.status_code == 200:
            # print(response.text)

            pattern1 = re.compile('<div.*?class="item">.*?<div.*?class="pic">.*?<a.*?href="(.*?)">',re.S)
            # 去掉所有换行符
            url = re.findall(pattern1, response.text

            for i in url:
                urls.append(i)
    return urls

def parse_url(urls):
    
    for i in range(0, 50, 1):
        res = requests.get(urls[i], headers = headers, allow_redirects=False)
        if res.status_code == 200:
            soup = BeautifulSoup(res.text, 'lxml')
            # 爬取电影名称
            name = soup.find('span', property="v:itemreviewed")
            names.append(name.text)            

            # 爬取导演名
            director = soup.find('a', rel="v:directedBy")
            directors.append(director.text)
           
            #爬取类型
            typ =soup.find('span', property="v:genre")[1:]
           typs.append(typ.text)
            
            # 爬取明星
            star_save = []
            for star in soup.find_all('a', rel="v:starring"):
                star_save.append(star.text)
                stars.append(star_save)


            # 爬取制片国家
            #<span class="pl">制片国家/地区:</span> 美国<br>
            country = soup.find('span', text='制片国家/地区:').next_sibling[1:]
            countrys.append(country)


            # 爬取影片语言
            # <span class="pl">语言:</span>
            language = soup.find('span', text='语言:').next_sibling[1:]
            languages.append(language)
            
            #爬取评分
            sorce = soup.find('span', class_="rating_num")
            sorces.append(sorce.text)

# print(directors)
# print(true_director)
# print(a)
if __name__ == '__main__':
    base = base_urls(base_url)
    parse_url(base)
    print(countrys)
    print(directors)
    print(languages)
    print(names)
    print(typs)
    print(sorces)
    #
    # 最后我们将数据写入到一个excel表格里
    info ={'Filmname':names, 'Directors':directors, 'Country':countrys, 'Languages':languages, 'typs':typs, "sorce":sorces}
    pdfile = pandas.DataFrame(info)
   
    pdfile.to_excel('DoubanFilm.xlsx', sheet_name="豆瓣电影")
复制代码

 

 


2.对数据进行清洗和处理(10)复制代码df = pd.DataFrame(pd.read_excel('DoubanFilm.xlsx'),columns=['Numbers','Filmname','Directors','Country','Languages','typs','score'])print(df.head())

# 读取excel文件

df.drop('Filmname', axis=1, inplace = True)
df.drop('Directors', axis=1, inplace = True)
df.drop('Languages', axis=1, inplace = True)
print(df.head())
# 删除无效行与列
print(df.isnull().sum()) print(df.isna().head()) # 统计缺失值 print(df.isna().head()) # 查找重复值
复制代码

得到下面的数据



4.数据分析与可视化(例如:数据柱形图、直方图、散点图、盒图、分布图)(15分)

复制代码
plt.rcParams['font.sans-serif']=['STSong']
# 显示中文
plt.rcParams['axes.unicode_minus']=False
# 用来正常显示负号

x = df.typs
y = df['Numbers'][:50]
plt.xlabel('类型')
plt.ylabel('排名')
plt.plot()
plt.scatter(x,y)
plt.title("排名与类型比较图")
plt.show()
#散点图

sns.lmplot(x='score',y='Numbers',data=df)
#线性图
复制代码

5.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变量之间的回归方程(一元或多元)(10分)。

复制代码
X = df.score
Y = df.Numbers  
def func(params, x):
        a, b, c = params
        return a*x*x+b*x+c
def error(params,x,y):
     return func(params,x)-y    
def main(a,b,c):
    p0 = [0,0,0]
    Para=leastsq(error,p0,args=(X,Y))
    a,b,c=Para[0]    
    print("a=",a,"b=",b,"c=",c) 
    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.grid()
    plt.show()
main()
#一元二次回归方程
复制代码


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

复制代码
  1 import requests
  2 from bs4 import BeautifulSoup
  3 import re
  4 import pandas
  5 from matplotlib import pyplot as plt
  6 import numpy as np
  7 import scipy as sp
  8 import pandas as pd
  9 from matplotlib import pyplot as plt
 10 import matplotlib
 11 import seaborn as sns
 12 from scipy.optimize import leastsq
 13 
 14 headers = {
 15     'Host':'movie.douban.com',
 16     'Origin':'movie.douban.com',
 17     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36',
 18 }
 19 base_url = 'https://movie.douban.com/top250?start={}&filter='
 25 response = requests.get('https://movie.douban.com/top250?start=0&filter=', headers = headers, allow_redirects=False)
 26 if response.status_code == 200:
 27     # print(response.text)
 28     pass
 29 
 30 pattern1 = re.compile('<div.*?class="item">.*?<div.*?class="pic">.*?<a.*?href="(.*?)">', re.S) # 去掉所有换行符,并用正则表达式去匹配每一个页面的具体电影
 31 urls = re.findall(pattern1, response.text)
 32 
 33 directors = [] # 导演名
 34 
 35 names = [] # 电影名称
 36 
 37 stars = [] # 主演人物
 38 
 39 countrys = [] # 电影拍摄地

 41 languages = [] # 电影语言种类
 42 
 43 typs = [] # 电影类型
 44 
 45 sorces = [] #评分
 46 
 47 # <span property="v:itemreviewed">肖申克的救赎 The Shawshank Redemption</span>
 48 # <a href="/celebrity/1047973/" rel="v:directedBy">弗兰克·德拉邦特</a>
 49 # <a href="/celebrity/1054521/" rel="v:starring">蒂姆·罗宾斯</a>
 50 def base_urls(base_url):
 51     urls = []
 52 
 53     # for i in range(0, 250, 25):
 54     #     true_url = base_url.format(i)
 55     #     print(true_url)
 56     for i in range(0, 50, 25):
 57         true_url = base_url.format(i)
 58 
 59         response = requests.get(true_url, headers=headers, allow_redirects=False)
 60         if response.status_code == 200:
 61             # print(response.text)
 62 
 63             pattern1 = re.compile('<div.*?class="item">.*?<div.*?class="pic">.*?<a.*?href="(.*?)">',re.S)
 64             # 去掉所有换行符,并用正则表达式去匹配每一个页面的具体电影
 65             url = re.findall(pattern1, response.text)
 66             # 因为这里是用findall,他返回的是一个列表,如果我们直接append,会导致列表嵌套,故我们这里用个for循环提取出列表的元素再append进去
 67 
 68             for i in url:
 69                 urls.append(i)
 70     return urls
 71 
 72 def parse_url(urls):
 73     
 74     for i in range(0, 50, 1):
 75         res = requests.get(urls[i], headers = headers, allow_redirects=False)
 76         if res.status_code == 200:
 77             soup = BeautifulSoup(res.text, 'lxml')
 78             # 爬取电影名
 79             name = soup.find('span', property="v:itemreviewed")
 80             names.append(name.text)            
 81 
 82             # 爬取导演
 83             director = soup.find('a', rel="v:directedBy")
 84             directors.append(director.text)
 85            
 86             #爬取类型
 87             typ =soup.find('span', property="v:genre")[1:]
 88             typs.append(typ.text)
 89             
 90             # 爬取明星
 91             star_save = []
 92             for star in soup.find_all('a', rel="v:starring"):
 93                 star_save.append(star.text)
 94                 stars.append(star_save)
 95 
 96 
 97             # 爬取制片国家
 98             #<span class="pl">制片国家/地区:</span> 美国<br>
 99             country = soup.find('span', text='制片国家/地区:').next_sibling[1:]
100             countrys.append(country)
101 
102 
103             # 爬取影片语言
104             # <span class="pl">语言:</span>
105             language = soup.find('span', text='语言:').next_sibling[1:]
106             languages.append(language)
107             
108             #爬取评分
109             sorce = soup.find('span', class_="rating_num")
110             sorces.append(sorce.text)
111 
112 # print(directors)
113 # print(true_director)
114 # print(a)
115 if __name__ == '__main__':
116     base = base_urls(base_url)
117     parse_url(base)
118     print(countrys)
119     print(directors)
120     print(languages)
121     print(names)
122     print(typs)
123     print(sorces)
124     125     # 最后我们将数据写入到一个excel表格里
126     info ={'Filmname':names, 'Directors':directors, 'Country':countrys, 'Languages':languages, 'typs':typs, "sorce":sorces}
127     pdfile = pandas.DataFrame(info)
128    
129     pdfile.to_excel('DoubanFilm.xlsx', sheet_name="豆瓣电影")
130 
131 #读取excel
132 df = pd.DataFrame(pd.read_excel('DoubanFilm.xlsx'),columns=['Numbers','Filmname','Directors','Country','Languages','typs','score'])
133 print(df.head())
134 
135 # 删除无效行与列
136 df.drop('Filmname', axis=1, inplace = True)
137 df.drop('Directors', axis=1, inplace = True)
138 df.drop('Languages', axis=1, inplace = True)
139 print(df.head())
140 
141 print(df.isnull().sum())
142 # 返回0,表示没有空值
143 print(df.isna().head())
144 # 统计缺失值
145 print(df.isna().head())
146 # 查找重复值
147 plt.rcParams['font.sans-serif']=['STSong']
148 # 显示中文
149 plt.rcParams['axes.unicode_minus']=False
150 # 用来正常显示负号
151 
152 x = df.typs
153 y = df['Numbers'][:50]
154 plt.xlabel('类型')
155 plt.ylabel('排名')
156 plt.bar(x,y)
157 plt.title("排名与类型比较图")
158 plt.show()
159 #柱状图
160 
161 x = df.typs
162 y = df['Numbers'][:50]
163 plt.xlabel('类型')
164 plt.ylabel('排名')
165 plt.plot()
166 plt.scatter(x,y)
167 plt.title("排名与类型比较图")
168 plt.show()
169 #散点图
170 
171 sns.lmplot(x='score',y='Numbers',data=df)
172 #线性图
173 
174 X = df.score
175 Y = df.Numbers  
176 def func(params, x):
177         a, b, c = params
178         return a*x*x+b*x+c
179 def error(params,x,y):
180      return func(params,x)-y    
181 def main(a,b,c):
182     p0 = [0,0,0]
183     Para=leastsq(error,p0,args=(X,Y))
184     a,b,c=Para[0]    
185     print("a=",a,"b=",b,"c=",c) 
186     plt.scatter(X,Y,color="green",label=u"评分分布",linewidth=2)
187     x=np.linspace(0,30,20)
188     y=a*x*x+b*x+c
189     plt.plot(x,y,color="red",label=u"回归方程直线",linewidth=2)     
190     plt.title("电影排名和评分关系图")
191     plt.legend()
192     plt.grid()
193 plt.show() 194 main() #一元二次回归方程
复制代码

 

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

经过对主题数据的分析与可视化可以更直观的了解数据
2.对本次程序设计任务完成的情况做一个简单的小结。

通过此次作业了解到了对于函数熟悉应用重要性以及

通过对代码不断的修改,对于python有进一步的认识

posted @ 2020-09-24 19:54  欲榜指  阅读(2015)  评论(0编辑  收藏  举报