爬取优酷电影top250数据分析

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

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

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

思路:对网页进行分析,通过爬虫读取数据存入excel,对数据清洗分析

难点:数据的处理

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

# <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页面解析

爬取优酷电影top250数据分析

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

爬取优酷电影top250数据分析
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.youku.com/top250?start={}&filter='





response = requests.get('https://movie.youku.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">蒂姆·罗宾斯</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)
            # 因为这里是用findall,他返回的是一个列表,如果我们直接append,会导致列表嵌套,故我们这里用个for循环提取出列表的元素再append进去

            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="豆瓣电影")
爬取优酷电影top250数据分析

 

 

爬取优酷电影top250数据分析
2.对数据进行清洗和处理(10)

爬取优酷电影top250数据分析
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())
# 返回0,表示没有空值
print(df.isna().head())
# 统计缺失值
print(df.isna().head())
# 查找重复值
爬取优酷电影top250数据分析

爬取优酷电影top250数据分析



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

爬取优酷电影top250数据分析
plt.rcParams['font.sans-serif']=['STSong']
# 显示中文
plt.rcParams['axes.unicode_minus']=False
# 用来正常显示负号

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

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)
#线性图
爬取优酷电影top250数据分析

爬取优酷电影top250数据分析爬取优酷电影top250数据分析爬取优酷电影top250数据分析

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

爬取优酷电影top250数据分析
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()
#一元二次回归方程
爬取优酷电影top250数据分析

爬取优酷电影top250数据分析


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

爬取优酷电影top250数据分析
  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='
 20 
 21 
 22 
 23 
 24 
 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 = [] # 电影的出产地
 40 
 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()
195 #一元二次回归方程
爬取优酷电影top250数据分析

 

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

可以更直观的了解数据
2.对本次程序设计任务完成的情况做一个简单的小结。

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

通过对代码不断的修改,对于python有更深的认识

上一篇:Python:python抓取豆瓣电影top250


下一篇:Python爬虫学习之爬取豆瓣音乐Top250存入Excel表格中