爬取豆瓣电影榜单构建知识图谱

文/Kingshine 图片来源于网络
♚
自我介绍:KingShine目前在北京定居的一名软件工程师。其主要研究领域涵盖数据分析与自然语言处理,并涉及大数据相关技术。渴望与志同道合的伙伴携手前进。
本文作者已成为Python中文社区专栏项目的成员
想要掌握知识图谱的相关内容。却因缺乏相关数据只好自行寻找相关资料。于是决定将豆瓣电影作为获取资源的平台使用。其网址为:
https://movie.douban.com/top250?start=0&filter=

一、分析问题
主页面上呈现的信息较为完整;细致地观察后会发现演员相关信息缺失;解析网站的源代码。

通过直接抓取网页内容(即主页面),可能会导致信息遗漏。随后决定访问每部电影的详细页码进行数据抓取,并以第一个电影为例说明操作流程:打开网页后,在搜索栏输入关键词并提交搜索请求后即可查看相关信息。

信息较为完整后, 经研究决定, 数据将从电影详细页进行提取。在构建知识图谱时, 首先需要选择所要存储的字段。综合考量各位观众的兴趣, 重点分析导演与演员之间的关系, 同时也会涉及电影类型等信息, 最终确定将爬取的数据字段包括导演、演员、电影及其类型。
-
电影名称
-
导演
-
演员
-
电影类型
本文的操作过程步骤如下:
第一步:从主页上获取所有电影详细页面的URL地址,并保存相关信息。
第二步:遍历上一步生成的电影地址列表。
第三步:通过数据处理构建知识图谱中的实体名称及其关联关系。
具体来说,在知识图谱构建过程中,默认将每部电影的具体名称作为节点名称,并记录其相关的属性信息描述。
-
电影结点(电影ID,电影名称,标签)
-
导演结点(导演ID,导演名称,标签)
-
演员结点(演员ID,演员名称,标签)
-
类型结点(类型ID,类型名称,标签)
关系:
-
导演——电影关系(导演)
-
演员——电影关系(出演)
-
导演——演员关系(合作)
-
电影——类型关系(属于)
第四步:将结点和关系导入Neo4j,生成图谱
二、爬取数据
最初采用Scrapy框架进行数据采集工作时发现,在处理网页内容的过程中发现了一个高效的 URL 提取模块;该模块能够快速从网页中提取出符合特定需求的数据 URLs;所获取的数据 URLs 通常呈现以下格式:

下面对电影详细页进行爬取。
最初尝试继续使用Scrapy一段时间后发现电影、导演以及类型的数据都能成功获取到了;但演员的数据却始终无法获取到。后来我才意识到演员数据是通过JavaScript动态生成的;这实在是浪费了不少时间啊;于是决定换用requests+BeautifulSoup来爬取数据
代码如下:
读取详细页URL列表

遍历URL列表,爬取每个页面信息,将每个页面的信息存储在results列表

将爬取结果导出到CSV文件

导出的文件如下:

三、生成结点和关系
数据收集完毕后,在下一步骤中需要提取出可以直接导入Neo4j数据库的结点与关系信息
-
电影结点(电影ID,电影名称,标签)
-
导演结点(导演ID,导演名称,标签)
-
演员结点(演员ID,演员名称,标签)
-
类型结点(类型ID,类型名称,标签)
提取结点的主要代码如下:
下面主要获得电影、导演、演员、类型的集合,方便ID编码

下面生成电影、导演、演员、类型的ID

拼接结点数据

生成结点文件

关系:
-
导演——电影关系(导演)
-
演员——电影关系(出演)
-
导演——演员关系(合作)
-
电影——类型关系(属于)
读取以上生成的结点文件

遍历文件,拼接出关系表,主要代码如下:

导出到CSV

这样所需要的结点和关系文件就生成好了

director.csv文件格式如下:

relationship_director_film.csv文件格式如下:

四、导入Neo4j,生成图谱
使用如下语句导入

需要注意的是, 这种导入方法需要确保数据库中不存在movie.db, 否则会导致错误发生. 因为Neo4j默认使用graph.db作为默认数据库, 所以在完成导入操作后, 需要调整 neo4j.conf 配置文件, 以便能够查看生成的数据库表结构. 具体操作步骤如下:

重新启动Neo4j后,你就会看到你的数据了。
我们来查看一下效果。


zhi
支
chi
持
zuo
作
zhe
者

长按扫码鼓励作者

重点推荐
重点推荐
全面探析几种Python静态类型检查工具及其应用
通过Python语言来进行数据分析和处理网易云音乐平台上的热门歌曲列表
在Python中文社区提供介绍几款功能模块的服务类公众号

▼ 长按扫码上方二维码或点击下方阅读原文
免费成为社区注册会员 ,会员可以享受更多权益
