网络爬虫之王者荣耀会

news/2024/11/20 1:21:24/

网络爬虫之王者荣耀会

因为需要,所以创造。 ——某开源社区


喜欢玩手游的朋友们应该都玩过某讯的王者农药,鄙人作为一个手游渣渣也玩过几次,常用英雄为亚瑟、安琪拉、鲁班…。玩几局就被其中每个英雄唯美的UI设计所吸引(但是最常玩还是射击类游戏,有喜欢玩的可以关注私聊我呦),但是对所有的英雄的荣耀并不太了解。所以为了了解每个英雄的典故,我从昨天10点到次日2点,撸代码撸出了这个开源程序(因为需要,所以创造

说说这个程序

模块和技术栈

首先这个程序主要包括两个部分,分别是数据抓取和处理数据展示。主要使用的技术栈为:

  • Java8
  • Okhttp (应用层)
  • Jsoup (数据解析)
  • JSP+CSS(界面有点丑,哈哈)
看一下实际效果(哈哈,真丑)在这里插入图片描述
看看实现核心代码吧

接口

// 解析
public interface Parser {void parser() throws ExecutionException, InterruptedException;
}
// 抓取
public interface Crawler<T,R> {String doGet(String uri, Map<T,R> headers);default void setHttpHeaders(Request.Builder builder, Map<T,R> headers){if(headers == null || headers.isEmpty()){return ;}for(Map.Entry<T,R> entry : headers.entrySet()){builder.addHeader(String.valueOf(entry.getKey()),String.valueOf(entry.getValue()));}}
}

抓取公共方法

public class HttpCrawler implements Crawler<String,String> {private OkHttpClient httpClient = new OkHttpClient();private static HttpCrawler instance = new HttpCrawler();@Overridepublic String doGet(String uri, Map<String,String> headers) {assert uri != null;Request.Builder httpBuilder = new Request.Builder();// 设置请求头部setHttpHeaders(httpBuilder,headers);Request request = httpBuilder.url(uri).build();Response response;String page = "";try{response = httpClient.newCall(request).execute();if(!response.isSuccessful()){throw new HttpStatusException(http_error.getMsg(),response.code(),uri);}ResponseBody responseBody = response.body();if(Objects.nonNull(responseBody)){byte[] bytes = responseBody.bytes();page = new String(bytes,Charsets.GB2312.name());}} catch (IOException e) {e.printStackTrace();}return page;}public static HttpCrawler getInstance() {return instance;}
}

解析英雄

public class KingParser implements Parser {private static KingParser kingParser = new KingParser();private StoryParser storyParser = StoryParser.getInstance();private String page;private List<Hero> heros = new ArrayList<>();private ExecutorService executors = Executors.newCachedThreadPool(new ThreadFactory() {AtomicInteger integer = new AtomicInteger();@Overridepublic Thread newThread(@NotNull Runnable r) {return new Thread(r,"parser-thread-"+integer.getAndIncrement());}});@Overridepublic void parser() throws ExecutionException, InterruptedException {Document document = Jsoup.parse(page);if(document == null || StringUtils.isEmpty(document.body().html())){return;}Elements heroBox = document.getElementsByClass(WebAppConfig.kingClassName);Elements heroLists = heroBox.get(0).getElementsByTag(li.name());long start;System.out.println("开始时间==="+(start=System.currentTimeMillis()));AtomicInteger count = new AtomicInteger();for(Element element : heroLists){Hero hero = new Hero();count.getAndIncrement();Future<Object> submit = executors.submit(() -> {Elements aTag = element.getElementsByTag(a.name());String uri = WebAppConfig.baseUri + aTag.attr(href.name());hero.setDetail(parserStory(uri));hero.setHero(aTag.get(0).getElementsByTag(img.name()).get(0).attr(alt.name()));hero.setPicture("http:" + aTag.get(0).getElementsByTag(img.name()).get(0).attr(src.name()));return hero;});heros.add((Hero) submit.get());}//4922System.out.println("结束时间==="+(System.currentTimeMillis()-start));System.out.println("共抓取:"+count.get());}public static KingParser getInstance(){return kingParser;}private String parserStory(String uri){storyParser.setUri(uri);storyParser.parser();return storyParser.getStory();}public void setPage(String page) {this.page = page;}public List<Hero> getHeros(){if(CollectionUtils.isEmpty(heros)){try {parser();} catch (ExecutionException | InterruptedException e) {e.printStackTrace();}}return heros;}
}

解析故事

public class StoryParser implements Parser{private String uri;private String story;private HttpCrawler httpCrawler = HttpCrawler.getInstance();private static StoryParser storyParser = new StoryParser();@Overridepublic void parser() {String detailPage = httpCrawler.doGet(uri, null);Document parse = Jsoup.parse(detailPage);Element heroStory = parse.getElementById("hero-story");Element element = heroStory.getElementsByClass("pop-bd").get(0);story = element.html();}public String getStory() { return story; }public void setUri(String uri) { this.uri = uri; }public static StoryParser getInstance() { return storyParser; }
}
代码还有需要优化的地方
  • 缓存:每次处理都需要多次请求解析,可以使用缓存替代。
  • 界面:界面不够美观,可以使用Javascript和CSS3进行页面动态化。

Github欢迎提issue

Github地址

关注我

在这里插入图片描述


http://www.ppmy.cn/news/303545.html

相关文章

Python爬虫之一:十几行代码下载王者荣耀所有皮肤

起因&#xff1a;前两天在公众号上看到一篇文章内容就是爬取王者荣耀的皮肤&#xff0c;但是内容太大概了&#xff0c;如果跟着他做肯定做不出来&#xff0c;所以我打算自己做。 之前接触过爬虫还是几年前爬取豆瓣电台的歌曲&#xff0c;那时候用的C&#xff0c;json解析还要用…

王者荣耀全皮肤

import os import timeimport requestsheroUrl https://pvp.qq.com/web201605/js/herolist.json headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36}# 创建目录文件 def makedir(x…

python爬取王者荣耀所有皮肤

文章目录 一、目标二、环境三、分析网页和url四、发现问题五、代码代码1代码2json文件夹代码&#xff1a;温馨提示 效果 一、目标 爬取王者荣耀英雄的所有的皮肤保存到文件夹 二、环境 用到的爬虫的requests 三、分析网页和url 1.英雄库的url&#xff1a;https://pvp.qq.…

华擎主板bios设置图解_华擎主板bios设置_华擎主板bios设置图解_asrock主板bios设置...

华擎主板bios设置篇一:华擎主板BIOS文字说明 华擎主板BIOS文字说明 BIOS 設置程序(BIOS SETUP UTILITY) 簡介 本部分說明如何運用B I O S 設置程序配置您的系統。主板上的快閃存儲器 儲存著B I O S 設置程序。當您啟動電腦時,您可以運行B I O S 設置程序。 請在開機自檢(POST…

华擎主板bios设置图解_华擎主板BIOS设置程序手册.pdf

您所在位置&#xff1a;网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbsp计算机硬件与维护 华擎主板BIOS设置程序手册.pdf20页 本文档一共被下载&#xff1a;次,您可全文免费在线阅读后下载本文档。 下载提示 1.本站不保证该用户上传的文档完整性…

华擎主板bios设置图解_华擎主板bios设置硬盘启动方法

想知道怎么设置华擎主板的BIOS为硬盘启动吗?下面是学习啦小编带来华擎主板bios设置硬盘启动方法的内容&#xff0c;欢迎阅读! 华擎主板bios设置硬盘启动方法&#xff1a; 1、上下方向键移动到Advanced BIOS Features&#xff0c;按回车键&#xff0c;进入下一界面 启动顺序为:…

解决华擎J3455主板DSM兼容性问题

传送门 破题升级BIOS制作 AmiSetupWriter 启动盘修改 BIOS参考文献版权声明 原本华擎 J3455 是最接近 DS918 原厂配置的主板&#xff0c;乃黑群晖之上品&#xff0c;但却因为华擎的骚操作&#xff0c;导致这款主板安装 DSM 时会出现各种奇奇怪怪的问题&#xff0c;启动慢&#…

全景看房vr全景展示,获得360度全景式视角实时交互体验

当在马路边收到地产广告传单&#xff0c;相信大部分人会直接无视或者扔掉&#xff0c;相比地产商付出大量的物料和人力成本来说&#xff0c;收效甚微&#xff0c;难以产生高收益。VR全景沉浸式看房体验以全新的体验式选房购房&#xff0c;打造差异化的服务体验&#xff0c;有效…