进入到电影网,首先对url进行简单的处理,我们发现该网站有10页,每页有10部电影。这是猫眼top100的第一页url形式
https://maoyan.com/board/4?offset=0 通过对url的分析,可以发现url中的offset参数每增加一页就会增加10.
由于猫眼电影网的反爬技术,可以通过请求头来反反爬!如果不写请求头headers有可能会被封IP。这里我的代码中只写了一个headers就可以抓到信息,一般来讲,一个请求头即可OK,但是如果依旧不能抓到信息,我们可以升级一下我们的爬虫,可以写n个请求头,然后通过随机模块来随机选择一个headers,如果做到这一步,那么大部分反爬技术都阻止不了你的爬虫了。当然爬虫的升级,我这里只是提供一种方法。
(抓取HTML页面信息的工具)
再查看网页源代码,利用XPath或者正则表达式来进行信息获取。
XPath讲解
正则讲解
# 导入相关库
import requests
from lxml import etree
# 请求头headers,避免反爬技术
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
}
# 定义电影的信息列表,格式为:序号、名字、时间、主演
message = []
# 由于猫眼top100网的特殊性,可以以10*10的形式来获取信息
for i in range(10):
url = "https://maoyan.com/board/4?offset=" + str(i * 10)
response = requests.get(url, headers=headers)
html = response.text
data = etree.HTML(html) # 初始化
passage = []
# 利用XPath来爬取猫眼的HTML页面
for h in range(10):
# 电影的序号
number = data.xpath('//div[@class="main"]/dl/dd/i/text()')
passage.append(number[h])
# 电影的名字
name = data.xpath('//div[@class="movie-item-info"]//p[@class="name"]/a/text()')
passage.append(name[h])
# 电影的上映时间
time = data.xpath('//p[@class="releasetime"]/text()')
passage.append(time[h])
# 电影主演
star = data.xpath('//p[@class="star"]/text()')
passage.append(star[h])
# 电影评分
# score = data.xpath('//p[@class="score"]/i/text()')
# passage.append(score[h])
message.append(passage)
# print(passage)
# print(message[0])
# 这里将电影信息列表message进一步处理,以every_movie_list列表的形式来展示
# every_html是每页电影的数据
every_movie_list = []
for every_html in message:
x = 0
m = 0
n = 4
while x <= 9:
every_movie = every_html[m:n]
m += 4
n += 4
x += 1
every_movie_list.append(every_movie)
# print(every_movie_list)
# 定义时间列表
timelist = []
# 抓取每部电影的上映时间,添加到时间列表timelist中
for everymovie_time in every_movie_list:
# print(everymovie_time[2])
timelist.append(everymovie_time[2][5:9])
# print(timelist)
# 经过对时间列表中的时间查看,大致可分为八个时间段,可定义八个时间段的列表
yearone = []
yeartwo = []
yearthree = []
yearfour = []
yearfive = []
yearsix = []
yearseven = []
yeareight = []
# 将时间列表中的时间进行分类
for year in timelist:
num = int(year)
if num <= 1950:
yearone.append(year)
elif 1950 < num <= 1960:
yeartwo.append(year)
elif 1960 < num <= 1970:
yearthree.append(year)
elif 1970 < num <= 1980:
yearfour.append(year)
elif 1980 < num <= 1990:
yearfive.append(year)
elif 1990 < num <= 2000:
yearsix.append(year)
elif 2000 < num <= 2010:
yearseven.append(year)
elif 2010 < num <= 2020:
yeareight.append(year)
print(yearone)
print(yeartwo)
print(yearthree)
print(yearfour)
print(yearfive)
print(yearsix)
print(yearseven)
print(yeareight)
print(len(yearone))
print(len(yeartwo))
print(len(yearthree))
print(len(yearfour))
print(len(yearfive))
print(len(yearsix))
print(len(yearseven))
print(len(yeareight))
# 以猫眼电影上架时间做条形图
from matplotlib import pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\SimSun.ttc")
x = ["1950年之前","1950-1960年","1960-1970年","1970-1980年","1980-1990年","1990-2000年","2000-2010年","2010-2020年"]
y = [2,3,3,1,4,25,31,31]
fig = plt.figure(figsize=(13,8),dpi=80)
ax = fig.add_subplot(1,1,1)
plt.bar(range(len(x)),y,width=0.5,color="pink")
plt.xticks(range(len(x)),x,fontproperties=my_font,rotation=0)
plt.grid(alpha=0.4)
ax.set_title('各年份电影上架数量条形图',fontproperties=my_font)
ax.set_xlabel('年份时间段',fontproperties=my_font)
plt.savefig("./年份条形图")
plt.show()
条形图的形式如下:
简单的可视化展示可以直观的看到各年份电影上架数目!
以上代码只是以时间分类的方式进行了可视化的展示,可视化展示可以以各种形式思路来进行展示,再或者以电影的评分高低来进行可视化展示。
爬取信息的思路和上面相同,url,headers,XPath。
只是在使用XPath的时候,我们发现网页源代码在评分部分由俩部分组成,如下图,例如 8.8 是由 8 和 .8 组成。所以对代码要有所改变
# 导入相关库
import requests
from lxml import etree
# 请求头
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
}
# 定义电影信息列表
message = []
for i in range(10):
url = "https://maoyan.com/board/4?offset=" + str(i * 10)
response = requests.get(url, headers=headers)
html = response.text
data = etree.HTML(html) # 初始化
# passage1则是评分源代码的前半部分
passage_1 = []
# passage2则是评分源代码的后半部分
passage_2 = []
for h in range(10):
# 利用XPath分别爬取评分的俩部分信息
score_1 = data.xpath('//p[@class="score"]/i[@class="integer"]/text()')
score_2 = data.xpath('//p[@class="score"]/i[@class="fraction"]/text()')
passage_1.append(score_1[h])
passage_2.append(score_2[h])
# 将爬取到评分的俩部分信息进行合并,和网页显示的评分数字一样
passage_3 = []
for i in range(len(passage_1)):
xxx = passage_1[i] + passage_2[i]
passage_3.append(xxx)
# 将最后爬取到的评分通通添加到message信息列表中
message.append(passage_3)
print(message)
socrelist = []
for everysocrelist in message:
for everysocre in everysocrelist:
socrelist.append(everysocre)
print(socrelist)
print(len(socrelist))
from matplotlib import pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname=r"c:\windows\fonts\simsun.ttc")
x = range(100)
y = socrelist
fig = plt.figure(figsize=(10,7),dpi=80)
ax = fig.add_subplot(1,1,1)
plt.scatter(x,y,color="orange")
plt.grid(alpha=0.4)
ax.set_title('电影评分分部散点图',fontproperties=my_font)
plt.savefig('./猫眼评分散点图')
plt.show()