我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么用Java实现网站聚合工具

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么用Java实现网站聚合工具

这篇文章主要介绍“怎么用Java实现网站聚合工具”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么用Java实现网站聚合工具”文章能帮助大家解决问题。

    原理

    可以把互联网上的网站看做一张巨大的连通图,不同的网站处于不同的连通块中,然后以广度优先算法遍历这个连通块,就能找到所有的网站域名,利用广度优先算法遍历该连通块的结构可以抽象为:

    怎么用Java实现网站聚合工具

    然后,我们对该网站的返回内容进行分词,剔除无意义的词语和标点符号,就得出该网站首页的关键词排序,我们可以取词频在(10,50)区间范围内的为关键词,然后将这些关键词作为网站主题,把网站的信息放到以该词为名字的markdown文件中备用。

    同理,我们也对该网站返回内容的title部分进行分词,因为title是网站开发者对网站功能的浓缩,也比较重要,同理,也将这些关键词作为网站主题,把网站的信息放到以该词为名字的markdown文件中备用。

    最后,我们只需要从这些文件中人工做筛选,或者以这些数据放到elasticsearch中,做关键词搜索引擎即可。以达到想用的时候随时去拿的目的。

    不过,当你遍历连通块没有收敛时,得到的数据还是很少的,某些分类往往只有一两个网站。

    实现代码

    页面下载

    页面下载我使用的是httpClient,前期考虑用playwrite来做,但是两者性能差距太大,后者效率太低了,所以舍弃了部分准确性(即web2.0技术的网站,前者无法拿到数据),所以准确的说我实现的仅仅是web1.0的网站分类搜索引擎的页面下载功能。

    public SendReq.ResBody doRequest(String url, String method, Map<String, Object> params) {    String urlTrue = url;    SendReq.ResBody resBody = SendReq.sendReq(urlTrue, method, params, defaultHeaders());    return resBody;}

    其中,SendReq是我封装的一个httpClient的类,只是实现了一个页面下载的功能,你可以替换为RestTemplate或者别的发起http(s)请求的方法。

    解析返回值中的所有链接

    因为是连通块遍历,那么定义的连通网站就是该网站首页里面所有的外链的域名所在的站,所以我们需要提取链接,直接使用正则表达式提取即可。

    public static List<String> getUrls(String htmlText) {    Pattern pattern = Pattern.compile("(http|https):\\/\\/[A-Za-z0-9_\\-\\+.:?&@=\\/%#,;]*");    Matcher matcher = pattern.matcher(htmlText);    Set<String> ans = new HashSet<>();    while (matcher.find()){        ans.add(DomainUtils.getDomainWithCompleteDomain(matcher.group()));    }    return new ArrayList<>(ans);}

    解析返回值中的title

    title是网站开发者对网站功能的浓缩,所以很有必要将title解析出来做进一步处理

    public static String getTitle(String htmlText){    Pattern pattern = Pattern.compile("(?<=title\\>).*(?=</title)");    Matcher matcher = pattern.matcher(htmlText);    Set<String> ans = new HashSet<>();    while (matcher.find()){        return matcher.group();    }    return "";}

    去除返回值中的标签

    因为后续步骤需要对网站返回值进行分词,所以需要对页面中的标签和代码进行去除。

    public static String getContent(String html) {    String ans = "";    try {        html = StringEscapeUtils.unescapeHtml4(html);        html = delHTMLTag(html);        html = htmlTextFormat(html);        return html;    } catch (Exception e) {        e.printStackTrace();    }    return ans;}public static String delHTMLTag(String htmlStr) {    String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式    String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式    String regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式    Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);    Matcher m_script = p_script.matcher(htmlStr);    htmlStr = m_script.replaceAll(""); //过滤script标签    Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);    Matcher m_style = p_style.matcher(htmlStr);    htmlStr = m_style.replaceAll(""); //过滤style标签    Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);    Matcher m_html = p_html.matcher(htmlStr);    htmlStr = m_html.replaceAll(""); //过滤html标签    return htmlStr.trim();}

    分词

    分词算法使用之前讲NLP入门的文章里面提到的hanlp即可

    private static Pattern ignoreWords = Pattern.compile("[,.0-9_\\- ,、:。;;\\]\\[\\/!()【】*?“”()+:|\"%~<>——]+");public static Set<Word> separateWordAndReturnUnit(String text) {    Segment segment = HanLP.newSegment().enableOffset(true);    Set<Word> detectorUnits = new HashSet<>();    Map<Integer, Word> detectorUnitMap = new HashMap<>();    List<Term> terms = segment.seg(text);    for (Term term : terms) {        Matcher matcher = ignoreWords.matcher(term.word);        if (!matcher.find() && term.word.length() > 1 && !term.word.contains("�")) {            Integer hashCode = term.word.hashCode();            Word detectorUnit = detectorUnitMap.get(hashCode);            if (Objects.nonNull(detectorUnit)) {                detectorUnit.setCount(detectorUnit.getCount() + 1);            } else {                detectorUnit = new Word();                detectorUnit.setWord(term.word.trim());                detectorUnit.setCount(1);                detectorUnitMap.put(hashCode, detectorUnit);                detectorUnits.add(detectorUnit);            }        }    }    return detectorUnits;}

    获取分词结果的数量前十个

    这里为了去掉词频过多的词的干扰,所以只取词频小于50的词的前十

    public static List<String> print2List(List<Word> tmp,int cnt){    PriorityQueue<Word> words = new PriorityQueue<>();    List<String> ans = new ArrayList<>();    for (Word word : tmp) {        words.add(word);    }    int count = 0;    while (!words.isEmpty()) {        Word word = words.poll();        if (word.getCount()<50){            ans.add(word.getWord() + " " + word.getCount());            count ++;            if (count >= cnt){                break;            }        }    }    return ans;}

    方法就是放到优先队列中一个一个取出来,优先队列是使用大顶堆实现的,所以取出来一定是有序的。如果想了解大顶堆的朋友,可以看我前面的文章。
    值得注意的是,优先队列中放入的类必须是可排序的,所以,这里的Word也是可排序的,简化的代码如下:

    public class Word implements Comparable{    private String word;    private Integer count = 0;    ... ...    @Override    public int compareTo(Object o) {        if (this.count >= ((Word)o).count){            return -1;        }else {            return 1;        }    }}

    好了,现在准备工作已经做好了。下面开始实现程序逻辑部分。

    遍历网站连通块

    利用广度优先遍历网站连通块,之前的文章有专门讲利用队列写广度优先遍历。现在就使用该方法。

    public void doTask() {    String root = "http://" + this.domain + "/";    Queue<String> urls = new LinkedList<>();    urls.add(root);    Set<String> tmpDomains = new HashSet<>();    tmpDomains.add(DomainUtils.getDomainWithCompleteDomain(root));    while (!urls.isEmpty()) {        String url = urls.poll();        SendReq.ResBody html = doRequest(url, "GET", new HashMap<>());        System.out.println("当前的请求为 " + url + " 队列的大小为 " + urls.size() + " 结果为" + html.getCode());        if (html.getCode().equals(0)) {            ignoreSet.add(DomainUtils.getDomainWithCompleteDomain(url));            try {                GenerateFile.createFile2("moneyframework/generate/ignore", "demo.txt", ignoreSet.toString());            } catch (IOException e) {                e.printStackTrace();            }            continue;        }        OnePage onePage = new OnePage();        onePage.setUrl(url);        onePage.setDomain(DomainUtils.getDomainWithCompleteDomain(url));        onePage.setCode(html.getCode());        String title = HtmlUtil.getTitle(html.getResponce()).trim();        if (!StringUtils.hasText(title) || title.length() > 100 || title.contains("�")) continue;        onePage.setTitle(title);        String content = HtmlUtil.getContent(html.getResponce());        Set<Word> words = Nlp.separateWordAndReturnUnit(content);        List<String> wordStr = Nlp.print2List(new ArrayList<>(words), 10);        handleWord(wordStr, DomainUtils.getDomainWithCompleteDomain(url), title);        onePage.setContent(wordStr.toString());        if (html.getCode().equals(200)) {            List<String> domains = HtmlUtil.getUrls(html.getResponce());            for (String domain : domains) {                int flag = 0;                for (String i : ignoreSet) {                    if (domain.endsWith(i)) {                        flag = 1;                        break;                    }                }                if (flag == 1) continue;                if (StringUtils.hasText(domain.trim())) {                    if (!tmpDomains.contains(domain)) {                        tmpDomains.add(domain);                        urls.add("http://" + domain + "/");                    }                }            }        }    }}

    调用测试

    @Servicepublic class Task {    @PostConstruct    public void init(){        new Thread(new Runnable() {            @Override            public void run() {                while (true){                    try {                        HttpClientCrawl clientCrawl = new HttpClientCrawl("http://www.mengwa.store/");                        clientCrawl.doTask();                    }catch (Exception e){                        e.printStackTrace();                    }                }            }        }).start();    }}

    关于“怎么用Java实现网站聚合工具”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    怎么用Java实现网站聚合工具

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    怎么用Java实现网站聚合工具

    这篇文章主要介绍“怎么用Java实现网站聚合工具”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么用Java实现网站聚合工具”文章能帮助大家解决问题。原理可以把互联网上的网站看做一张巨大的连通图,不
    2023-06-29

    怎么使用Python+tkinter实现网站下载工具

    今天小编给大家分享一下怎么使用Python+tkinter实现网站下载工具的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。开发
    2023-07-05

    网站截图工具EyeWitness怎么用

    这篇文章主要介绍了网站截图工具EyeWitness怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。网站截图工具EyeWitness在网页分析和取证中,往往需要大批量的网站
    2023-06-04

    Bing网站管理员工具怎么用

    这篇文章给大家分享的是有关Bing网站管理员工具怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、验证过程要使用Bing网站管理员工具,首先需要验证你拥有网站管理权限。有两个验证方法,按照Bing要求在网站
    2023-06-13

    C#聚合复用原则怎么实现

    这篇文章主要介绍“C#聚合复用原则怎么实现”,在日常操作中,相信很多人在C#聚合复用原则怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#聚合复用原则怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来
    2023-06-29

    java集合排序工具类怎么使用

    Java集合排序工具类可以使用`java.util.Collections`类中的静态方法来实现。以下是使用Java集合排序工具类的基本步骤:导入`java.util.Collections`类:在使用Java集合排序工具类之前,首先需要导
    2023-10-26

    SpringBoot整合java诊断工具Arthas怎么用

    这篇文章主要介绍了SpringBoot整合java诊断工具Arthas怎么用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot整合java诊断工具Arthas怎么用文章都会有所收获,下面我们一起
    2023-07-05

    利用Java怎么实现一个超时工具类

    本文章向大家介绍利用Java怎么实现一个超时工具类的基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向对象理论,允许程
    2023-06-06

    怎么使用Java实现进制转换工具类

    本文小编为大家详细介绍“怎么使用Java实现进制转换工具类”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么使用Java实现进制转换工具类”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。原理低进制转换到高进制的时
    2023-07-05

    网站过期域名查询工具怎么使用

    网站过期域名查询工具可以帮助您查询一个域名是否已经过期或即将过期。以下是使用该工具的步骤:1. 打开一个网站过期域名查询工具,例如Whois查询工具。2. 在搜索框中输入您要查询的域名。3. 点击“查询”按钮,等待查询结果。4. 查询结果会
    2023-06-07

    怎么用vbs结合wget实现下载网站图片

    本篇内容介绍了“怎么用vbs结合wget实现下载网站图片”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!vbs 函数过程:1. 调用wget:
    2023-06-08

    K8S实用工具之怎么合并多个kubeconfig

    这篇文章主要介绍“K8S实用工具之怎么合并多个kubeconfig”,在日常操作中,相信很多人在K8S实用工具之怎么合并多个kubeconfig问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”K8S实用工具之怎
    2023-07-05

    怎么用vbs实现的exe2swf工具

    小编给大家分享一下怎么用vbs实现的exe2swf工具脚本代码,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!代码如下:dim AsoR,FlashFileName
    2023-06-08

    Java怎么实现文字转语音工具箱

    本篇内容主要讲解“Java怎么实现文字转语音工具箱”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java怎么实现文字转语音工具箱”吧!整合这里我们使用百度云的人工智能语音合成API,个人用户拥有
    2023-06-03

    Java怎么实现的图片上传工具类

    这篇文章给大家分享的是有关Java怎么实现的图片上传工具类的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体如下:package com.gcloud.common;import javax.imageio.Im
    2023-05-31

    怎么使用Java工具类实现高效编写报表

    本篇内容主要讲解“怎么使用Java工具类实现高效编写报表”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Java工具类实现高效编写报表”吧!为什么使用java代码写报表对于报表数据大部分情
    2023-07-04

    Java怎么用递归实现树形结构的工具类

    本文小编为大家详细介绍“Java怎么用递归实现树形结构的工具类”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java怎么用递归实现树形结构的工具类”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。需求描述有时候,我
    2023-07-05

    Linux怎么使用awk文本处理工具实现多行合并

    这篇文章主要介绍“Linux怎么使用awk文本处理工具实现多行合并”,在日常操作中,相信很多人在Linux怎么使用awk文本处理工具实现多行合并问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux怎么使用
    2023-06-13

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录