Java豆瓣电影爬虫——抓取电影详情和电影短评数据
一直想做个这样的爬虫:定制自己的种子,爬取想要的数据,做点力所能及的小分析。正好,这段时间宝宝出生,一边陪宝宝和宝妈,一边把自己做的这个豆瓣电影爬虫的数据采集部分跑起来。现在做一个概要的介绍和演示。
动机
采集豆瓣电影数据包括电影详情页数据和电影的短评数据。
电影详情页如下图所示

需要保存这些详情字段如导演、编剧、演员等还有图中右下方的标签。
短评页面如下图所示

需要保存的字段有短评所属的电影名称,每条评论的详细信息如评论人名称、评论内容等。
数据库设计
有了如上的需求,需要设计表,其实很简单,只需要一张电影详情表movie和一张电影短评表comments,另外还需要一张存储网页提取的超链接的记录表record。
movie表

- movieId:主键,自增长
- Name:电影名
- Director:导演
- Scenarist:编剧
- Actors:主演
- Type:类型
- Country:制片国家/地区
- Language:语言
- releaseData: 上映日期
- Runtime: 片长
- ratingNum:豆瓣评分
- Tags:标签
comments表

- commentId:主键,自增长
- commentInfo:评论内容
- commentAuthor:评论者
- commentAuthorImgUrl:评论者头像链接
- commentVote:评论点赞数
- commentForMovie:评论的电影名
- recordId:链接record表,暂时未用到
record表

- recordId:主键,自增长
- URL:爬取解析的超链接
- Crawled:是否被爬过
注意:数据库设计是在不断调整的,比如之前设计了一张tags表,用于存储每部电影的标签,经过调整发现直接放到movie中作为一个字段更加方便,又比如comments表中,commentForMovie是后来加上的,方便查找当前的评论针对哪部电影。
使用的技术
语言:Java(语言是一门工具,网上用python,java,nodejs比较多)
数据库:Mysql(轻便易用)
解析页面:Jsoup(比较熟悉httpparser,虽然功能强大,但是稍显繁琐,这里用Jsoup,因为其为类javascript语法)、正则表达式(对于一些结构比较奇怪的dom结构,采用了正则表达式的方式来提取信息,其实也可以用xpath,但是xpath极易受dom结构变化而失效)
比如对于网页源码如下
<!DOCTYPE html>
<html lang="zh-cmn-Hans" class="ua-windows ua-webkit">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="renderer" content="webkit">
<meta name="referrer" content="always">
<title>
肖申克的救赎 (豆瓣)
</title> ..... <meta name="keywords" content="肖申克的救赎,The Shawshank Redemption,肖申克的救赎影评,剧情介绍,电影图片,预告片,影讯,在线购票,论坛,肖申克的救赎在线观看,肖申克的救赎高清,肖申克的救赎在线播放">
<meta name="description" content="肖申克的救赎电影简介和剧情介绍,肖申克的救赎影评、图片、预告片、影讯、论坛、在线购票、肖申克的救赎在线观看、高清、在线播放"> ......... <div id="info">
<span ><span class='pl'>导演</span>: <span class='attrs'><a href="/celebrity/1047973/" rel="v:directedBy">弗兰克·德拉邦特</a></span></span><br/>
<span ><span class='pl'>编剧</span>: <span class='attrs'><a href="/celebrity/1047973/">弗兰克·德拉邦特</a> / <a href="/celebrity/1049547/">斯蒂芬·金</a></span></span><br/>
<span class="actor"><span class='pl'>主演</span>: <span class='attrs'><a href="/celebrity/1054521/" rel="v:starring">蒂姆·罗宾斯</a> / <a href="/celebrity/1054534/" rel="v:starring">摩根·弗里曼</a> / <a href="/celebrity/1041179/" rel="v:starring">鲍勃·冈顿</a> / <a href="/celebrity/1000095/" rel="v:starring">威廉姆·赛德勒</a> / <a href="/celebrity/1013817/" rel="v:starring">克兰西·布朗</a> / <a href="/celebrity/1010612/" rel="v:starring">吉尔·贝罗斯</a> / <a href="/celebrity/1054892/" rel="v:starring">马克·罗斯顿</a> / <a href="/celebrity/1027897/" rel="v:starring">詹姆斯·惠特摩</a> / <a href="/celebrity/1087302/" rel="v:starring">杰弗里·德曼</a> / <a href="/celebrity/1074035/" rel="v:starring">拉里·布兰登伯格</a> / <a href="/celebrity/1099030/" rel="v:starring">尼尔·吉恩托利</a> / <a href="/celebrity/1343305/" rel="v:starring">布赖恩·利比</a> / <a href="/celebrity/1048222/" rel="v:starring">大卫·普罗瓦尔</a> / <a href="/celebrity/1343306/" rel="v:starring">约瑟夫·劳格诺</a> / <a href="/celebrity/1315528/" rel="v:starring">祖德·塞克利拉</a></span></span><br/>
<span class="pl">类型:</span> <span property="v:genre">剧情</span> / <span property="v:genre">犯罪</span><br/> <span class="pl">制片国家/地区:</span> 美国<br/>
<span class="pl">语言:</span> 英语<br/>
<span class="pl">上映日期:</span> <span property="v:initialReleaseDate" content="1994-09-10(多伦多电影节)">1994-09-10(多伦多电影节)</span> / <span property="v:initialReleaseDate" content="1994-10-14(美国)">1994-10-14(美国)</span><br/>
<span class="pl">片长:</span> <span property="v:runtime" content="142">142 分钟</span><br/>
<span class="pl">又名:</span> 月黑高飞(港) / 刺激1995(台) / 地狱诺言 / 铁窗岁月 / 消香克的救赎<br/>
<span class="pl">IMDb链接:</span> <a href="http://www.imdb.com/title/tt0111161" target="_blank" rel="nofollow">tt0111161</a><br> </div> </div> <div id="interest_sectl">
<div class="rating_wrap clearbox" rel="v:rating">
<div class="rating_logo">豆瓣评分</div>
<div class="rating_self clearfix" typeof="v:Rating">
<strong class="ll rating_num" property="v:average">9.6</strong>
<span property="v:best" content="10.0"></span>
<div class="rating_right ">
<div class="ll bigstar50"></div>
<div class="rating_sum">
<a href="collections" class="rating_people"><span property="v:votes">740373</span>人评价</a>
</div>
</div>
</div> <span class="stars5 starstop" title="力荐">
5星
</span>
<div class="power" style="width:64px"></div>
<span class="rating_per">81.5%</span>
<br /> <span class="stars4 starstop" title="推荐">
4星
</span>
<div class="power" style="width:12px"></div>
<span class="rating_per">16.2%</span>
<br /> <span class="stars3 starstop" title="还行">
3星
</span>
<div class="power" style="width:1px"></div>
<span class="rating_per">2.1%</span>
<br /> <span class="stars2 starstop" title="较差">
2星
</span>
<div class="power" style="width:0px"></div>
<span class="rating_per">0.1%</span>
<br /> <span class="stars1 starstop" title="很差">
1星
</span>
<div class="power" style="width:0px"></div>
<span class="rating_per">0.1%</span>
<br /> </div>
<div class="rating_betterthan">
好于 <a href="/typerank?type_name=剧情&type=11&interval_id=100:90&action=">99% 剧情片</a><br/>
好于 <a href="/typerank?type_name=犯罪&type=3&interval_id=100:90&action=">99% 犯罪片</a><br/>
</div>
</div> </div> ......... <!-- sindar19a-docker--> <script>_SPLITTEST=''</script>
</body> </html>
可以通过如下代码来解析相应字段(其中有用Jsoup和正则表达式的)
for (Element info : infos) {
if (info.childNodeSize() > 0) {
String key = info.getElementsByAttributeValue("class", "pl").text();
if ("导演".equals(key)) {
movie.setDirector(info.getElementsByAttributeValue("class", "attrs").text());
} else if ("编剧".equals(key)) {
movie.setScenarist(info.getElementsByAttributeValue("class", "attrs").text());
} else if ("主演".equals(key)) {
movie.setActors(info.getElementsByAttributeValue("class", "attrs").text());
} else if ("类型:".equals(key)) {
movie.setType(doc.getElementsByAttributeValue("property", "v:genre").text());
} else if ("制片国家/地区:".equals(key)) {
Pattern patternCountry = Pattern.compile(".制片国家/地区:</span>.+[\\u4e00-\\u9fa5]+.+[\\u4e00-\\u9fa5]+\\s+<br>");
Matcher matcherCountry = patternCountry.matcher(doc.html());
if (matcherCountry.find()) {
movie.setCountry(matcherCountry.group().split("</span>")[1].split("<br>")[0].trim());// for example: >制片国家/地区:</span> 中国大陆 / 香港 <br>
}
} else if ("语言:".equals(key)) {
Pattern patternLanguage = Pattern.compile(".语言:</span>.+[\\u4e00-\\u9fa5]+.+[\\u4e00-\\u9fa5]+\\s+<br>");
Matcher matcherLanguage = patternLanguage.matcher(doc.html());
if (matcherLanguage.find()) {
movie.setLanguage(matcherLanguage.group().split("</span>")[1].split("<br>")[0].trim());
}
} else if ("上映日期:".equals(key)) {
movie.setReleaseDate(doc.getElementsByAttributeValue("property", "v:initialReleaseDate").text());
} else if ("片长:".equals(key)) {
movie.setRuntime(doc.getElementsByAttributeValue("property", "v:runtime").text());
}
}
}
movie.setTags(doc.getElementsByClass("tags-body").text());
movie.setName(doc.getElementsByAttributeValue("property", "v:itemreviewed").text());
movie.setRatingNum(doc.getElementsByAttributeValue("property", "v:average").text());
对于服务端返回不同状态的http status,本程序对于如304,401,403,404等都采取了丢弃处理,不作解析。
效果展示

record表记录

movie表记录

comments表记录

以上只是一个爬取数据的后台实现雏形,还有很多细节的问题需要解决。后期可能会补上环境搭建以及遇到的问题和解决方法相关的文章。
Java豆瓣电影爬虫——使用Word2Vec分析电影短评数据
程序爬取控制在豆瓣可接受范围内,不会给豆瓣服务器带来很大的压力,写此程序也是个人把玩,绝无恶意,万望豆瓣君谅解^_^
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。
Java豆瓣电影爬虫——抓取电影详情和电影短评数据的更多相关文章
- python爬虫---抓取优酷的电影
最近在学习爬虫,用的BeautifulSoup4这个库,设想是把优酷上面的电影的名字及链接爬到,然后存到一个文本文档中.比较简单的需求,第一次写爬虫.贴上代码供参考: # coding:utf-8 i ...
- JAVA使用Gecco爬虫 抓取网页内容(附Demo)
JAVA 爬虫工具有挺多的,但是Gecco是一个挺轻量方便的工具. 先上项目结构图. 这是一个 JAVASE的 MAVEN 项目,要添加包依赖,其他就四个文件.log4j.properties 加上三 ...
- java使用htmlunit工具抓取js中加载的数据
htmlunit 是一款开源的java 页面分析工具,读取页面后,可以有效的使用htmlunit分析页面上的内容.项目可以模拟浏览器运行,被誉为java浏览器的开源实现.这个没有界面的浏览器,运行速度 ...
- Python爬虫----抓取豆瓣电影Top250
有了上次利用python爬虫抓取糗事百科的经验,这次自己动手写了个爬虫抓取豆瓣电影Top250的简要信息. 1.观察url 首先观察一下网址的结构 http://movie.douban.com/to ...
- Java 实现 HttpClients+jsoup,Jsoup,htmlunit,Headless Chrome 爬虫抓取数据
最近整理一下手头上搞过的一些爬虫,有HttpClients+jsoup,Jsoup,htmlunit,HeadlessChrome 一,HttpClients+jsoup,这是第一代比较low,很快就 ...
- [Python] 抓取时光网的电影列表并生成网页
抓取时光网的电影列表并生成网页 源码 https://github.com/YouXianMing/BeautifulSoup4-WebCralwer 分析 利用BeautifulSoup进行分析网页 ...
- 怎么用Python写爬虫抓取网页数据
机器学习首先面临的一个问题就是准备数据,数据的来源大概有这么几种:公司积累数据,购买,交换,政府机构及企业公开的数据,通过爬虫从网上抓取.本篇介绍怎么写一个爬虫从网上抓取公开的数据. 很多语言都可以写 ...
- 利用Python网络爬虫抓取微信好友的签名及其可视化展示
前几天给大家分享了如何利用Python词云和wordart可视化工具对朋友圈数据进行可视化,利用Python网络爬虫抓取微信好友数量以及微信好友的男女比例,以及利用Python网络爬虫抓取微信好友的所 ...
- 爬虫抓取页面数据原理(php爬虫框架有很多 )
爬虫抓取页面数据原理(php爬虫框架有很多 ) 一.总结 1.php爬虫框架有很多,包括很多傻瓜式的软件 2.照以前写过java爬虫的例子来看,真的非常简单,就是一个获取网页数据的类或者方法(这里的话 ...
随机推荐
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- SQL Server相关书籍
SQL Server相关书籍 (排名不分先后) Microsoft SQL Server 企业级平台管理实践 SQL Server 2008数据库技术内幕 SQL Server性能调优实战 SQL S ...
- 07.LoT.UI 前后台通用框架分解系列之——强大的文本编辑器
LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/du ...
- 读python源码--对象模型
学python的人都知道,python中一切皆是对象,如class生成的对象是对象,class本身也是对象,int是对象,str是对象,dict是对象....所以,我很好奇,python是怎样实现这些 ...
- C#数组,List,Dictionary的相互转换
本篇文章会向大家实例讲述以下内容: 将数组转换为List 将List转换为数组 将数组转换为Dictionary 将Dictionary 转换为数组 将List转换为Dictionary 将Dicti ...
- 快递Api接口 & 微信公众号开发流程
之前的文章,已经分析过快递Api接口可能被使用的需求及场景:今天呢,简单给大家介绍一下微信公众号中怎么来使用快递Api接口,来完成我们的需求和业务场景. 开发语言:Nodejs,其中用到了Neo4j图 ...
- 【基于WinForm+Access局域网共享数据库的项目总结】之篇一:WinForm开发总体概述与技术实现
篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...
- Spring(三)__aop编程
aop( aspect oriented programming ) 面向切面编程,是对所有对象或者是一类对象编程 几个重要的概念: 1.切面(aspect):要实现的交叉功能,是系统模块化的一个切面 ...
- Android开发学习—— Broadcast广播接收者
现实中:电台要发布消息,通过广播把消息广播出去,使用收音机,就可以收听广播,得知这条消息.Android中:系统在运行过程中,会产生许多事件,那么某些事件产生时,比如:电量改变.收发短信.拨打电话.屏 ...
- oracle SEQUENCE 创建, 修改,删除
oracle创建序列化: CREATE SEQUENCE seq_itv_collection INCREMENT BY 1 -- 每次加几个 STA ...
