数据获取:豆瓣电影信息爬取


数据获取:豆瓣电影信息爬取

MangoGO 芒狗狗


  有开源的豆瓣电影评论数据集,但是主要是评论数据,电影信息很少。没有找到电影信息数据集,也就是主键为电影,附带电影的特征的数据,特征包括导演、演员、时长、电影类型、出品公司、制片地区、上映时间、对白语言、剧情描述等。

  拿来主义行不通,那就只好自己动手丰衣足食。好在豆瓣电影网站的结构并不复杂,爬取其电影信息的工作并不会耽误太多的时间。本文记录电影信息爬取的一种可行过程,不一定为最佳方案,欢迎读者发表自己的想法。

0 写在前面

  本文并不是专业的爬虫指导,只能说是一位爬虫菜鸟的学习笔记。仅就粗浅的爬虫经验,总结一些探索过程。

0.1 内容网站用户旅程

  我们先总结内容网站成熟用户一般旅程。成熟用户省略了注册、信息补充等内容,日常活跃的基本行为就是消费网站提供的内容,所以最终目标都是抵达感兴趣的内容详情页或使用页。除了内容详情页,用户访问较多的页面还有:

  (1)首页
  进入网站的第一页,一般将罗列重要的栏目,每个栏目下罗列重要的频道,每个频道下罗列推荐的内容。当然,如果某个栏目是最重要的,首页上可能只展示这个栏目下的频道及包含的推荐内容。次要的栏目需要用户在网页的上部或左边等显眼的位置去切换。首页上往往也提供了进入内容筛选页的入口,一般是点击搜索栏、带有“更多”、“库”等字眼的按钮。

  (2)栏目
  有些内容网站提供的内容类型很丰富,先将内容按照大类区分,分别放置在不同的栏目,比如视频类网站,给长视频、短视频分别设置栏目。用户点击栏目后,一般都会罗列该栏目下的常用频道,每个频道下展示少许推荐内容。

  (3)频道
  进入频道后一般网页就会变得比较简单了,往往只包含内容列表,有些会提供少量内容基础属性的筛选和排序,内容列表在多个页码(上一页、下一页)上展示,或者根据用户滑动页码的动作对列表进行刷新。

  (4)内容筛选
  上面几个页面上出现的默认内容往往都是网站推荐曝光的,而内容全量的筛选展示页则赋予了用户更多选择权,该页也是用户能从网站上看到最全的内容列表的位置,一般将栏目、频道和其他重要内容特征作为筛选选项。我们只要遍历必要的选项的所有排列组合,将每种组合下的内容列表加载完毕,就能获取足够的内容列表。

功能大类
细分小类
内容列表
内容列表
进入
首页
栏目
频道
内容筛选/排行
内容详情/使用
图0-1 内容网站成熟用户一般旅程

  用户从上面几种页面都可以抵达内容详情页,所以有多种常见旅程:
  (1)用户进入首页后,可能被首页推送的内容吸引,直接进入内容详情/使用页。
  (2)用户进入首页后,选择栏目,被栏目内推送的内容吸引,直接进入内容详情/使用页。
  (3)用户进入首页后,选择栏目、频道,被频道内推送或筛选出的内容吸引,进入内容详情/使用页。
  (4)用户进入首页后,直奔内容筛选,按照喜好配置筛选选项、排序方式,点击结果列表中的兴趣内容,进入内容详情/使用页。

0.2 内容网站信息爬取一般步骤

  使用爬虫获取内容信息,也是要顺着这样的路线触达目标网页。上面的路径中,(1)(2)往往只会包含少了内容,(3)(4)一般会看到所有的上架内容。由此总结内容信息爬取的一般步骤:

  步骤1:确定完整的主体列表网页及网址组成规律
  我们想要爬取豆瓣电影网站上的电影信息,主体就是电影,相关的信息肯定是需要在具体某部电影独占的详情页获取,但是我们并不能直接知道所有电影的详情页的网址,必须从上一级链接的网页(电影清单页)中获取电影的列表,这个列表中往往直接包含了每部电影网址。
  但是一般网站不会将所有内容都放在一页上展示(但是也有),这未免有些无趣,也不便于用户在列表中获取兴趣内容。常见的做法是网站给一些单选筛选项设置了默认值,用户可以修改这些筛选项,每次只展示选项下单个值覆盖的内容列表;遍历这些选项值就能看到所有的内容列表。这些选项有时会作为参数在网址上体现,这样我们就能获取所有的内容列表页的网址。

  步骤2:确定主体信息网页及从主体列表网页获取主体信息网址的方式
  步骤1中的内容列表蕴含着跳转每个内容详情页的链接,我们可以先点击内容列表中的一些内容进入详情页,查看并记住页面网址,然后查看内容列表页的HTML代码,看看这些内容详情页网址在代码中的位置。如此我们便获取了所有内容详情页的网址。

  步骤3:确定从主体信息网页获取信息的方式
  进入内容详情页后,查看我们关心的信息在页面的位置和在代码位置。

1 豆瓣电影网站情况

  开始对豆瓣电影网站进行探索之前,需要先明确爬取这些数据是想用在一些自然语言处理的实验中,并不是有使用化意图。所以我们只需要获取足够数量的电影即可,最好在电影类型维度的关键枚举值上都有分布

1.1 电影清单页选择

  豆瓣电影首页如下图所示,从网页上面的导航栏来看,电影清单页就在选电影排行榜里。当然,这个网页结构比较简单,我们可以每个导航栏都点进去看看情况。

豆瓣电影首页

图1-1 豆瓣电影首页

  通过对该网站的探索,我们发现选电影排行榜都包含电影清单,相似但有略微的差别。

  (1)“选电影”

  该页面支持电影类型、地区、年代、标签多个维度的筛选,还能选择排序方式。我们最关注的是电影类型维度,需要在不同类型中都摘取一些电影。选定类型后,默认展示19部电影,每点击最下面的加载更多一次,会再添加20部电影。

  我们选定电影类型、排序方式后,这些设定并没有体现在网址上,所以爬虫代码中需要模拟鼠标点击功能,依次完成每种类型的选择和排序方式的选择(排序方式并不重要,但是我们还是希望摘取更有关注度的电影),并在每种类型下多次点击加载更多,点击次数取决于你准备每种类型摘取多少部电影。

豆瓣电影-选电影

图1-2 豆瓣电影-选电影

  (2)“排行榜”

  该页面支持电影类型的选择,支持在固定排序(看起来应该是按照打分排序)中选择排名区间,区间长度固定为10个百分点,但可以滑动选择区间的位置。电影清单默认展示20部电影,滚动鼠标到底部自动加载更多电影,也是每次增加20部。该网页提醒,那些没有打分的电影不会在这个网页上展示。没有打分的电影关注度也太低了,此处我们选择放弃这些电影。

  电影类型的选择和区间的选择都有规律地体现在网址上,这就为爬虫提供了很大的便捷。但是想要获取更多电影,还是需要在爬虫代码中多次模拟鼠标滚动到底部,并延时等待数据刷新。

豆瓣电影-排行榜

图1-3 豆瓣电影-排行榜

  对比来看,“排行榜”页面能满足我们的需要,且通过对网址的拼接处理,省去了很多页面点击的需求,对编码的要求较低。我们以此页面为突破口进一步探索背后的数据。

1.2 电影排行榜页探索

  (1)分类排行榜网址规律

  通过遍历排行榜页所有电影类型,观察网址变化情况,并通过修改网址各部分请求到的网页情况,总结网址各组成部分的作用如下:

https://movie.douban.com/typerank?type_name=类型名称&type=类型ID&interval_id= 排名区间&action=
前缀类型名称类型ID排名区间后缀
必须必须但不起作用必须必须可空

网址中对电影类型的筛选起作用的是type参数,类型名称和类型ID的对应关系我们总结如下:

表1-1 豆瓣电影-排行榜
序号类型ID类型名称
11纪录片
22传记
33犯罪
44历史
55动作
66情色
77歌舞
88儿童
910悬疑
1011剧情
1112灾难
1213爱情
1314音乐
1415冒险
1516奇幻
1617科幻
1718运动
1819惊悚
1920恐怖
2022战争
2123短片
2224喜剧
2325动画
2427西部
2528家庭
2629武侠
2730古装
2831黑色电影

  当然,表1-1内容最好是从“排行榜”网页的“更多类型”处获取。
  28种电影类型和10个排名区间排列组合,形成28×10=280个网址,遍历这些网址就能获取排行榜网页中的所有电影。

  确定排行榜网址后,每个网址还需要确定滚动到网页最下面加载更多电影的次数,网页加载出来后会显示符合筛选条件的电影的数量,与每次加载的电影数量相除就能知道需要额外加载的次数。例如图1-3中喜剧类型的排名100%~90%区间的电影数为646,需要再加载math.ceil(646 / 20 - 1)(=32)次才能完全展示。

  (2)排行榜页电影清单代码

  在该页面使用F12键或者在菜单栏调出开发者工具,选择查看栏目为元素(Edge、Chrome中为这个名称,FireFox中为查看器),点击左上角的鼠标指针图标(①位置),将鼠标指针移动到网页的电影清单区域(②位置)。可以看到鼠标指针到达的地方,被指定的位置的元素会被半透明的蓝色覆盖。不停地移动鼠标位置,确保我们选到了包含所有电影清单的最小范围,点击鼠标左键选定,元素中会跳到对应的代码块(③位置)。

  将鼠标指针移动到代码上,网页对应的元素依然会突出显示。我们展开③位置的代码,移动鼠标观察每行代码对应的元素,直到选中了具体某部电影的名称(点击电影名称可以跳转电影详情页),多次展开后可以看到④位置的代码情况。看起来我们似乎找到了电影详情页的网址。

豆瓣排行榜电影清单代码

图1-4 豆瓣电影-排行榜-电影清单背后代码

  ③位置的代码下包含了20条类似④位置的代码,每条都对应一部电影。如果我们向下滑动左边的网页加载更多的电影,右边的代码处也会刷新更多的电影对应的代码。

1.3 电影详情页探索

  点击图1-4中的某部电影链接进入电影详情页,可以看出图1-5网址与图1-4中④位置网址一致,这下我们终于确定了:电影详情页网址就在电影清单代码里。而且我们可以猜测,网址中最后一段数字就是该电影的编码。

  由此,我们从电影清单页到电影详情页的路径已经打通。接下来就是获取详情页的信息。

豆瓣电影详情页背后代码

图1-5 豆瓣电影详情页背后代码

  我们需要的信息都集中在网页的上面,至于下面的评论、获奖,我们暂时并不关心。继续使用1.2(2)中的方法探索电影详情页信息在代码中的位置,如图1-5所示。

2 爬虫关键代码

2.1 爬取全流程

  开始写代码之前需要有清晰的思路。再次梳理我们爬虫的过程:

  (1)打开“排行榜首页”,获取所有电影类型及对应的类型ID;
  (2)修改“分类排行榜”网址中的typeinterval_id参数的值,形成28个电影类型的280个分类分区间排行榜网址;
  (3)打开每个分类分区间排行榜网址,多次滚动到网页底部加载榜单中所有电影,获取电影名称和网址。由于一部电影会出现在多个类型中,最后获取的电影网址需要去重;
  (4)遍历每部电影的网址,获取电影关键属性信息。

豆瓣电影信息爬取全流程
catalog_url_ls
遍历完成
开始
获取电影清单网址列表
catalog_url_ls
模拟浏览器启动
遍历打开catalog_url_ls
模拟网页滚动到底
更新电影详情页网址列表
movie_url_ls
遍历打开movie_url_ls
获取电影详情页信息
movie_url_ls
遍历完成
结束

2.2 打开网址及滚动到底

  由于在电影排行榜网页中需要滚动底部,所以需要模拟浏览器打开网址及滚动到网页底部的动作。
  我们使用三方Python包selenium模拟浏览器相关行为,该三方包需要具备浏览器对应版本的驱动才能正常工作。如何安装请自行百度。我们此处使用的是chrome浏览器。

  (1)打开网址

from selenium import webdriver
from selenium.webdriver.chrome.service import Service


url = 'https://xxxxxxxxxx'

options = webdriver.ChromeOptions()
options.add_experimental_option('detach', True)

service = Service(executable_path=chromedriver_path)
browser = webdriver.Chrome(options=options, service=service,
                           keep_alive='True')
browser.get(url)

  (1)滚动到网页底部

js = "window.scrollTo(0, document.body.scrollHeight)"
browser.execute_script(js)

2.3 不同位置信息提取

  selenium提供了几种在html代码中定位目标元素的方法,可以按照xml路径(XPATH),可以按照标签名(TAG_NAME),可以按照分级名(CLASS_NAME)。本案例中使用如上三种定位方式就可以了,一些较复杂的定位可以分步抵达,即先定位到大区域,再在大区域中定位目标元素,较少不相关的内容的干扰。

  selenium的定位方法请自行百度,应该能找到更专业的教程。

  需要注意的是,得确定你想定位的元素在同类网页的不同实例中的定位值不会变化。例如,图1-5中的电影属性模块①②③,“导演”、“编剧”、“演员”等属性在大部分电影中都是具备的,且保持固定的排序,但是也有少部分电影缺失部分属性,或多了一些属性。属性的增多或较少会导致属性序号的变化,当我们使用XPATH方式获取定位时就会发生问题。此处“导演”的元素的XPATH为//*[@id="info"]/span[1]/span[2],其中第一个span表示整个①②③模块,“导演”位于这个模块的第一位,所以span[1]就能定位到“导演”所在行。第二个span定位的是导演姓名的元素,故而索引为2。如果某部电影没有导演信息,“编剧”在①②③模块中的顺序就由2变成了1。所以需要根据①②③模块的文本信息做相应的调整,动态修改xml路径:

'//*[@id="info"]/span[{}]/span[2]'.format(idx)

3 结果数据处理

3.1 电影详情页网址去重

  一部电影是多种类型的,所以按照上面获取电影清单的方式,我们会在多个类型下看到同一部电影,所以需要对最终获取的全部电影网址进行去重。

3.2 电影属性处理

  (1)电影名称
  非国产电影详情页的电影名称是中文名称加外文名称的组合,我们还是采用电影清单页面的中文名称。

  (2)多值属性
  导演、编剧、演员、类型、制片地区、语言、上映日期、片长、别名等属性都为多值,我们采取拼接处理,分隔符与豆瓣保持一致,为斜杆符号“/”。
  导演、编剧、演员除了文本信息,还有网址链接,跳转到创作者的主页。使用“|”对不同的网址进行隔离。

  (3)评分相关
  结果分、评论人数、不同打分的人数比例都使用单独的字段进行存储。

  (4)剧情简介
  存储之前先将文本中可能存在的表字段分隔符剔除。

3.3 样例数据

在这里插入图片描述

4 数据情况

  数据浅层分析后续单开一篇文章。
  数据下载:HuggingFace | CSDN

5 写在最后

  俗话说:爬虫写得好,牢饭吃到饱(不是)。合理利用网络资源,避免给别人带来麻烦和损失。

  代码可以在GitCode处获取。

  • 13
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MangoGO芒狗狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值