爬虫神器selenium之猫眼电影榜单实例
如果你在学习爬虫,那么你一定爬取过豆瓣或猫眼电影的榜单,但大多数教程都是用的requests+正则,但对于很多新手来讲,requests获取网页容易,但是用正则表达式解析网页就难的多了。那么,让我们告别看不懂,也写不好的正则吧,本文通过HTML解析器来爬取猫眼榜单电影,并基于爬取的数据做一个简单的数据分析。
1.爬虫
如果你看过网易云音乐上万首hiphop歌曲解析rapper们的最爱(爬虫篇)一文,那么selenium你一定熟悉,然而,那篇文章用到的PhantomJS已经被抛弃了,所以在使用的时候会显示warning。所以,本文需要用webdriver.Chrome()直接模拟浏览器。在开始之前,请确保已经正确安装好Chrome浏览器并配置好了ChromeDriver;另外,还需要正确安装Python的Selenium库。配置部分直接百度,就有大量文章介绍。
第一步呢,肯定是分析网页啦。
我们要爬取就是该部分的内容,通过翻页,观察一下url的变化。
第二页:
第三页:
聪明的你一定发现了,变化只是offset后面的值,也就是每页都加了10,倒推回第一页,对应的是offset=0。那么我们爬取页面的时候,只需要变换该部分就OK了。
网页分析的常规操作,看元素:
我们想要的就在<dl class="board-wrapper">下面的<dd>里面。在具体分析其中一个<dd>:
那么接下来就非常简单了。直接上代码:
1from tqdm import tqdm
2import time
3from selenium import webdriver
4from selenium.common.exceptions import TimeoutException, WebDriverException
5import pandas as pd
6
7def get_one_page(url):
8 try:
9 #打开浏览器窗口
10 driver = webdriver.Chrome()
11 driver.get(url)
12 data = driver.find_element_by_class_name("board-wrapper").find_elements_by_tag_name("dd")
13
14 for j in range(len(data)):
15 #获取电影名称
16 name.append(data[j].find_element_by_class_name("name").text)
17 #获取主演
18 star.append(data[j].find_element_by_class_name("star").text)
19 #上映时间
20 publish.append(data[j].find_element_by_class_name('releasetime').text)
21 #得分:整数+小数
22 score.append(data[j].find_element_by_class_name('integer').text + data[j].find_element_by_class_name('fraction').text)
23 time.sleep(5)
24 #关闭窗口
25 driver.quit()
26 return data
27 #报错重新获取
28 except TimeoutException or WebDriverException:
29 return get_one_page()
30
31name,star,publish,score=[],[],[],[]
32for i in tqdm(range(0,91,10)):
33 print("\n获取第{}个页信息!".format( (i//10) +1))
34 url = 'http://maoyan.com/board/4?offset='+str(i)
35 get_one_page(url)
36
37movie = {'name': name, 'star': star, 'publish': publish, 'score': score}
38movie = pd.DataFrame(movie, columns=['name', 'star', 'publish', 'score'])
39movie.to_csv("movie_top100.csv",encoding="utf_8_sig")
非常简单吧。
2.数据可视化
由于这次爬取的数据很少,这里也只是做了简单的可视化。
主演分布:
第一名是大家心中永远的哥哥:张国荣,100部电影电影,他主演的就有6部,其次是周星驰,梁朝伟。很意外吧,前三都是中国的,而且居然还都是香港的。
电影名称长度:
长度为4,5,6占了近3/4,看来电影名称不宜太短,也不宜太长啊。
发行国家:
虽然我们爬取的数据,没有发行国家这一项,但是通过观察,发现有一些电影的发行日期后面接了发行国家,所以我们将这部分数据拿出来,简单看看哪个国家的电影更优。
最多的是没有数据的。暂且不考虑它。单独看国家数据,美国遥遥领先,毕竟好莱坞嘛。日本、韩国紧随其后,擅长细腻、写实的电影风格看来很受人欢迎。
发现年份:
发行时间数据其实还有蛮多可做的,年份、月份、星期都能做可视化:
2011年左右是好电影的爆发期啊。90年代是港片的巅峰,也是佳片云集。
发行月份:
月份的话,简单的看,好像冬季发行的电影好片更多。
发行星期:
星期五是电影发行的集中段,可能和该时间段发行,有助于票房的原因吧,同理,没有星期天发行,也是怕影响票房,毕竟接下来大家都上班上学了。(0表示的是没有想过数据)
星期和评分:
其实,因为是top100的电影,他们的评分不会有多大的差距,所以可视化没有考虑分数,最后也只是做个简单的展示而已,还是能够看出,星期和评分之间没有什么关系,趋势非常平缓。
代码:
1import seaborn as sns
2import matplotlib.pyplot as plt
3plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']#指定默认字体
4plt.rcParams['axes.unicode_minus'] =False # 解决保存图像是负号'-'显示为方块的问题
5sns.set(font='SimHei') # 解决Seaborn中文显示问题
6
7data = pd.read_csv("movie_top100.csv")
8
9#电影明星分布
10data["star"] = data["star"].apply(lambda x: x.replace("主演:",""))
11data["star"] = data["star"].apply(lambda x:x.split(","))
12star=[]
13for i in range(100):
14 star.extend(data["star"][i])
15star = pd.value_counts(star)
16
17sns.set_context('talk')
18fig = plt.figure(figsize=(30, 10))
19ax = sns.barplot(x=star[:30].index, y=star[:30].values)
20ax.set_title('Rate of star')
21ax.set_xticklabels(star.index, rotation=90)
22
23#电影名字长度分布
24name_len = data["name"].apply(lambda x: len(x))
25name_len = name_len.value_counts()
26fig = plt.figure(figsize=(15, 15))
27plt.pie(name_len.values,labels=name_len.index,autopct='%1.2f%%') #画饼图(数据,数据对应的标签,百分数保留两位小数点)
28plt.title("电影名字长度")
29plt.show()
30
31#电影发行日期
32#发行国家
33data["country"] = data["publish"].apply(lambda x: x[15:] if len(x)>15 else '')
34#发行年月日
35data["time"] = data["publish"].apply(lambda x: x[5:15])
36data["year"] = data["time"].apply(lambda x: x[0:4])
37data["month"] = data["time"].apply(lambda x: x[5:7] if len(x)> 4 else '')
38data["day"] = data["time"].apply(lambda x: x[8:10] if len(x)> 4 else '')
39
40#新建立星期信息
41from datetime import date
42def getWeekday(row):
43 if len(row) <= 4:
44 return 0
45 else:
46 return date(int(row[0:4]), int(row[5:7]), int(row[8:10])).weekday() + 1
47data['weekday'] = data['time'].apply(getWeekday)
48
49#发行国家
50country = data["country"].value_counts()
51fig = plt.figure(figsize=(15,10))
52sns.barplot(country.index,country.values)
53fig.show()
54
55#对出行时间进行可视化
56year = data["year"].value_counts()
57year = year.sort_index()
58fig = plt.figure(figsize=(17,10))
59sns.pointplot(year.index,year.values,alpha=0.5)
60fig.show
61
62month = data["month"].value_counts()
63month = month.sort_index()
64fig = plt.figure(figsize=(15,10))
65sns.barplot(month.index,month.values)
66fig.show()
67
68weekday = data["weekday"].value_counts()
69weekday = weekday.sort_index()
70fig = plt.figure(figsize=(15,10))
71sns.barplot(weekday.index,weekday.values)
72fig.show()
73
74fig = plt.figure(figsize=(15,10))
75sns.boxplot(data["weekday"],data["score"])
76fig.show()
通过本文学习,是不是发现爬虫很简单啦。胡萝卜酱给大家的建议就是多练,熟能生巧,ヾ(◍°∇°◍)ノ゙!
最后是一条招聘广告