起因
恰逢诺兰导演的新片《敦刻尔克》即将在中国上映,作为诺兰导演的铁粉,印象中他的很多部电影都进入了IMDB TOP250的榜单,但是具体是多少部呢?他是不是IMDB TOP250 中作品最多的导演呢?哪些演员在这些电影中出镜最多呢?在这些问题的启发下,我准备写一个简单的爬虫脚本来获取我想要的数据。
分析
首先需要对工作的流程进行一个简单的分析。我们的目标是获取以下的数据:
- IMDB TOP250 中导演根据作品数量的排名
- IMDB TOP250 中演员根据作品数量的排名
要得到以上的数据,我们需要的原始数据包括:
- IMDB TOP250 的电影数据: 名称,评分
- 电影导演
- 电影演员
页面HTML分析
让我们先来看一下数据的来源,IMDB TOP250的网页。
可以看到在页面HTML文件中,我们可以得到的数据有电影的评分,电影的名字,电影的年份。但是导演和演员的数据呢?可以发现在页面上点击电影的名字,可以到达电影的详情页,而这个link也在HTML文件中。
我们接着观察电影的详情页。在HTML中我们可以获取到导演的信息
同时在Cast 的表中还可以获取到主要演员的信息
这样一来我们需要的数据就都有了。
数据库设计
要实现这种类型数据的排名和统计,关系型数据库更加合适。在这里,我的设计是用5个不同的表来记录不同的数据。同时我使用的是开源的MySQL数据库。
- 创建一个
imdb_movie
schema - 创建表
top_250_movies
用于存储电影的信息:电影名称name
, 电影的发行年份year
, 电影的评分rate
.
这里还有一个电影的ID, 这个值如何来生成呢?是自动增加呢还是用一个其他的值?在前面的HTML文件中,我观察到电影的链接中有一个tt0111161
的部分,所以我猜测0111161
就是这部电影在IMDB中的UUID,所以我决定用这个值作为这个表的id
值。
CREATE TABLE `top_250_movies` (
`id` int(11) NOT NULL,
`name` varchar(45) NOT NULL,
`year` int(11) DEFAULT NULL,
`rate` float NOT NULL,
PRIMARY KEY (`id`)
)
- 创建表
actors
和directors
来保存演员和导演的信息。
这个表的结构很简单,就是演员的id
和演员的name
. 而演员/导演的ID和前面的电影ID的思路类似,通过演员详情页链接中的ID来设置。
CREATE TABLE `actors` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
)
CREATE TABLE `directors` (
`id` int(11) NOT NULL,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
)
- 创建表
cast_in_movie
来保存演员出演电影的信息。
由于一个演员可以参演多部电影,而一个电影也有很多的演员,所以这里我会创建一个cast_id
来标示每一个出演的关系,这个表中的每一行数据记录了一个演员参演了一部电影。同时是分别使用actor_id
和movie_id
为Foreign Key与actors
和top_250_movies
关联。
CREATE TABLE `cast_in_movie` (
`cast_id` int(11) NOT NULL AUTO_INCREMENT,
`actor_id` int(11) NOT NULL,
`movie_id` int(11) NOT NULL,
PRIMARY KEY (`cast_id`),
KEY `actor_id_idx` (`actor_id`),
KEY `movie_id_idx` (`movie_id`),
CONSTRAINT `actor_id` FOREIGN KEY (`actor_id`) REFERENCES `actors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `movie_id` FOREIGN KEY (`movie_id`) REFERENCES `top_250_movies` (`id`) ON DELETE NO ACTION ON