由于博主前两天刚入门Java爬虫,并且自学了Jsoup的爬取和解析方式以及输入输出流的相关知识,因此打算检验一下目前的学习成果。在一番深思熟虑(x)后,毅然打算爬取王者荣耀官网全英雄全皮肤的壁纸。
爬取分析
1.首先进入王者荣耀官网英雄主页面(https://pvp.qq.com/web201605/herolist.shtml),右键点击检查,对主页进行分析。
2.观察英雄主页面源代码,可发现所有英雄都包含在ul标签(ul.herolist.clearfix)下的li标签中,而其中的li标签的href便是我们需要进入的英雄页面。
3.点击href的链接,进入到英雄页面。(这里我进入的是蒙恬的页面,多尝试进入几个英雄页面可以发现基本规律就是/herodetail/XXX.shtml,其中XXX为英雄编号)
观察英雄页面,其中ul标签(ul.pic-pf-list.pic-pf-list3)下的data-imgname属性内容是英雄皮肤名称字符串;而通过select选中“秩序猎龙者”,可以发现这个小图标来自于img标签内。这里注意了!img标签内的src属性的链接是小图标,而壁纸则是data-imgname属性的链接!
4.复制data-imgname属性内的链接粘贴进入,可以看到我们的爬取目标——英雄皮肤壁纸。多点几个英雄的链接地址进行观察,可找到规律。(前缀一样,即前缀都是:https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/;总体规律为:https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/ + 英雄编号 + / + 英雄编号 + -bigskin- + 皮肤顺序 + .jpg)
5.根据上述爬取分析,我们的爬取目标已经很明确了,这里来总结一下:
① 通过英雄主页面(https://pvp.qq.com/web201605/herolist.shtml)爬取英雄名称,英雄编号,英雄页面地址链接,便于进入各个英雄的详情页面,并在爬取时标记好当前正在爬取的英雄。
② 通过英雄详情页面爬取英雄的皮肤串,去除特殊符号并拆分保存到List列表中便于为之后爬取的英雄皮肤图片命名。
③ 组装好各个英雄皮肤壁纸链接,为之后下载保存到文件夹作准备。
目前思路已经很明确了,接下来进入按照爬取目标进行代码编写的实战篇。
实战演练
1.首先按照我们前面“爬取分析”模块的第一个目标进行代码编写,也就是通过英雄主页面爬取英雄名称,英雄编号,英雄页面地址链接。
public static void main(String[] args) throws IOException {
// 请求主页面
String url = "https://pvp.qq.com/web201605/herolist.shtml"; // 主页面
Connection connect = Jsoup.connect(url); // 创建连接
Document document = connect.get(); // 请求网页
// 解析获取英雄名称、英雄编号、英雄页面
Elements elements = document.select("ul.herolist.clearfix").select("li");
for(Element ele : elements) {
// 遍历每一个li节点
String hero = ele.select("a").select("img").attr("alt");
String hero_url = ele.select("a").attr("href");
String hero_id = hero_url.substring(hero_url.length()-9, hero_url.length()-6);
System.out.println("英雄:" + hero + ", 英雄编号:" + hero_id + ", 英雄页面:" + hero_url);
}
}
通过观察控制台的输出,可以看到从“云中君”到“廉颇”所有英雄爬取完毕。
这个模块没什么可说的,无非就是通过Jsoup循环遍历获取li节点集合,然后对其中的每个li节点集合进行解析输出。(之后输出可以调整为调用方法分别进入英雄详情页面进行壁纸下载)
2.编写英雄详情页面爬取方法heroPage,完成前述“爬取分析”模块中的第二个目标和第三个目标。
static void heroPage(String hero, String hero_id, String hero_url) throws IOException {
String url = "https://pvp.qq.com/web201605/" + hero_url;
Document doc = Jsoup.connect(url).get(); // 获取英雄页面源代码
Element ele = doc.select("ul.pic-pf-list.pic-pf-list3").get(0);
String pf = ele.attr("data-imgname"); // 找到皮肤串
pf = pf.replaceAll("\\d+", ""); // 通过正则表达式去除皮肤串中的数字
int pf_num = 0; // 假设皮肤数量为0
for(int i = 0; i < pf.length(); i++) {
pf_num = (pf.charAt(i) == "&".toCharArray()[0