写代码之前,我们先不要着急,先理一理思路。你知道,写代码最重要的就是思路,思路理顺了,可以说你的代码已经完成了一半。那剩下的一半干嘛?写bug,调bug呗🤣
标签,在这个li标签里面存放着这个电影相关的全部html代码:
再打开li标签,可以看到,每个li标签里面都是一个
class='item'
的
div
,这个div就是我们需要获取数据的最外层div了。然后我们从这个div往下看,找到对应数据存放的标签即可。
比如这个电影排名:
我们可以从下面的
em
标签里面找到,那我们只需要一层层往下解析这个html代码,找到这个
em
标签,获取出里面的文本就行了。其他的数据也是异曲同工,我们可以按照这个套路都找一下对应的标签的位置,然后抓取。
怎么样,很简单是吧?那么下面就开始写bug吧
撸代码
写代码之前先喝杯咖啡,润润肺,找找灵感,你知道5k程序员和50k程序员的差别在哪里吗?
仪式感!
我跟你说,仪式感非常重要,包括生活中也是,你不能把自己过成穷屌丝的样子,要不然这辈子抬不起头来,你要假装自己是亿万富翁,然后花钱去享受,再然后回到一穷二白。如果你非要问我为什么要有这段经历,那不就是死要面子活受罪么...
咳咳,扯远了,继续回到正题哈。
我这次使用的插件是
Jsoup
,相信很多小伙伴都听说过它的大名啊,没错,它是一个非常适合做网页html解析的第三方类库,而且它可以直接连接目标网址,获取数据,无需使用其他的http请求工具,非常的方便,适合小白。
第一步:创建maven工程
为什么使用maven工程?
那还用问啊,当然是方便啊,我总不能去网上下载jar包导进idea吧,那太low了,不符合我的气质啊,所以你自己拿捏了哈,同学。
创建maven工程具体的步骤我就不在这里赘述了,网上教程一搜一大堆。我们创建好工程后直接在pom里导入依赖:
<dependency>
<groupId>org.jsoupgroupId>
<artifactId>jsoupartifactId>
<version>1.13.1version>
dependency>
对,是她了,我们的主角
jsoup
。
接下来就开始撸了呗。因为我们请求的所有数据分为10页,所以我们写个循环,从0开始:
第一页的url是这样的:
https://movie.douban.com/top250?start=0&filter=
第二页的url是这样的:
https://movie.douban.com/top250?start=25&filter=
可以看出来,通过
start
这个参数可以控制切换分页,那么我们就在循环里制造这样的参数:
for (int i = 0; i 10; i++) {
int page = i * 25; // 制造分页参数
}
下面就开始通过
Jsoup
发送http请求获取网页html代码,这里的document就是整个文档对象,我们可以从中获取各种标签的数据。
Document document = Jsoup.connect("https://movie.douban.com/top250?start="+ page).get();
拿到文档对象后,我们就获取每个电影的div,分析网页可以看到,它的class是
item
所以我们通过
getElementsByClass
方法批量从网页中获取
class=item
的元素:
Elements items = document.getElementsByClass("item"); // 批量获取当前页中class=item的元素
然后开始遍历所有的
item
,依次获取他们的电影相关的数据:
for (Element item : items) {
// 每个item中都包含当前电影的所有数据
}
再来分析网页,依次拿到我们需要的数据
-
「电影排名」
很简单啊,直接获取
item
中第一个
em
标签的文本就可以了:
String num = item.getElementsByTag("em").get(0).text();
-
「电影名称」
获取
item
下的第一个
class=hd
div的第一个span的文本
String title = item.getElementsByClass("hd").get(0).getElementsByTag("span").get(0).text();
-
「演员信息、电影年份、国家、电影类型」
注意这里,演员信息在一个
p
标签里,但是
p
标签的文本分成了两部分,用
隔开,所以我们先要获取到
p
标签的html文本,然后根据
多html文本进行分割,分别获取
演员信息
和
电影年份
、
国家
、
电影类型
等数据:
String bd = item.getElementsByClass("bd").get(0).getElementsByTag("p").get(0).html();
String actor = bd.split("
")[0].replaceAll(" ", " "); // 演员信息,注意替换空格符号
String info = bd.split("
")[1].replaceAll(" ", " ");
String[] infos = info.split("/"); // 下面的三个数据通过 '/' 来分割
String year = infos[0].trim(); // 电影年份
String country = infos[1].trim(); // 国家
String type = infos[2].trim(); // 电影类型
-
「电影评分」
这个就比较简单了,直接获取第一个
class=rating_num
标签的文本就可以了:
String ratingNum = item.getElementsByClass("rating_num").get(0).text(); // 获取评分
-
「电影简评」
这个跟评分类似,获取第一个
calss=quote
标签的文本就可以了:
String quote = item.getElementsByClass("quote").get(0).text();
Ok,到这里所有的代码就写完了,怎么样,是不是跟着思路走分析起来很容易呢?你自己可以试试哦,这里是完整的代码:
for (int i = 0; i 10; i++) {
int page = i * 25;
Document document = Jsoup.connect("https://movie.douban.com/top250?start="+ page).get();
Elements items = document.getElementsByClass("item");
for (Element item : items) {
String num = item.getElementsByTag("em").get(0).text();
String title = item.getElementsByClass("hd").get(0).getElementsByTag("span").get(0).text();
String bd = item.getElementsByClass("bd").get(0).getElementsByTag("p").get(0).html();
String actor = bd.split("
")[0].replaceAll(" ", " ");
String info = bd.split("
")[1].replaceAll(" ", " ");
String[] infos = info.split("/");
String year = infos[0].trim();
String country = infos[1].trim();
String type = infos[2].trim();
String ratingNum = item.getElementsByClass("rating_num").get(0).text();
String quote = item.getElementsByClass("quote").get(0).text();
System.out.println("电影名次: " + num);
System.out.println("电影标题: " + title);
System.out.println("电影演员: " + actor);
System.out.println("电影年份: " + year);
System.out.println("国家: " + country);
System.out.println("电影类型: " + type);
System.out.println("电影评分: " + ratingNum);
System.out.println("电影简评: " + quote);
System.out.println("============================================");
}
}
写完之后,我们运行一下代码,看看代码有没有问题。
果然,出问题了,哈哈哈,很快哈,啪的一下就出来了。
这是个啥错误?
一看,数组越界了,我心中已经猜想到答案了,肯定是获取的数据缺少了点什么导致的。我们定位到问题行:
25
,也就是这段代码:
String quote = item.getElementsByClass("quote").get(0).text();
获取简评失败了。
再看是第几个电影的数据出问题:
第200个电影是好的,那就是说它的下一个
201
出问题了。我们翻到这一页看下网页是啥样的:
果然,这个名叫
哈利·波特与火焰杯
的电影没有简介,那就是说没这个标签啊,怪不得获取失败了。