使用Elasticsearch做站内搜索,简易搜索引擎。

1、 搭建集群

首先搭建和维护一个高效的 Elasticsearch 搜索引擎集群,为了优化中文搜索体验,集成 IK 分词器,显著提升搜索精度。


2、设计爬虫程序

该程序定时从网站抓取最新内容,并将其索引至 Elasticsearch中,确保了搜索数据的即时更新。(支持深度控制,防止页面链接回环)


3、设计搜索查询功能

包括基于点击量和内容相关性的复合排序算法,以便用户能够获得最优质的搜索结果。


4、设计动态更新词典机制

确保词典可以更新,并实现在不中断服务的情况下重建索引的功能,确保了搜索引擎在更新过程中的稳定性和可用性。(使用别名重建索引)

5、爬虫程序示例

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.13.1</version>
</dependency>

5.1、深度优先

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;

public class SimpleWebCrawler {

    private Set<String> visitedUrls = new HashSet<>();
    private int maxDepth;

    public SimpleWebCrawler(int maxDepth) {
        this.maxDepth = maxDepth;
    }

    public void crawl(String seedUrl, int currentDepth) {
        if (currentDepth > maxDepth || visitedUrls.contains(seedUrl)) {
            return;
        }
        try {
            Document doc = Jsoup.connect(seedUrl).get();
            saveHtmlPage(seedUrl, doc);
            visitedUrls.add(seedUrl);
            if (currentDepth < maxDepth) {
                Elements links = doc.select("a[href]");
                for (Element link : links) {
                    String nextUrl = link.absUrl("href");
                    crawl(nextUrl, currentDepth + 1);
                }
            }
        } catch (IOException e) {
            System.err.println("Error fetching URL: " + seedUrl);
        }
    }

    public void saveHtmlPage(String url, Document doc) {
        String fileName = "saved_pages/" + url.replaceFirst("^(http[s]?://www\\.|http[s]?://|www\\.)", "").replaceAll("[^a-zA-Z0-9]", "_") + ".html";
        try {
            Files.createDirectories(Paths.get("saved_pages"));
            Files.write(Paths.get(fileName), doc.outerHtml().getBytes());
            System.out.println("Saved: " + fileName);
        } catch (IOException e) {
            System.err.println("Error saving HTML page: " + fileName);
        }
    }

    public static void main(String[] args) {
        String seedUrl = "http://example.com"; // 替换为你的种子URL
        SimpleWebCrawler crawler = new SimpleWebCrawler(3); // 设置爬取深度为3
        crawler.crawl(seedUrl, 0);
    }
}

5.2、广度优先

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;

public class SimpleWebCrawlerBFS {

    private Set<String> visitedUrls = new HashSet<>();
    private int maxDepth;
    private Queue<UrlDepthPair> queue = new LinkedList<>();

    public SimpleWebCrawlerBFS(int maxDepth) {
        this.maxDepth = maxDepth;
    }

    public void crawl(String seedUrl) {
        queue.add(new UrlDepthPair(seedUrl, 0));

        while (!queue.isEmpty()) {
            UrlDepthPair current = queue.poll();
            String currentUrl = current.url;
            int currentDepth = current.depth;

            if (currentDepth > maxDepth || visitedUrls.contains(currentUrl)) {
                continue;
            }
            
            try {
                Document doc = Jsoup.connect(currentUrl).get();
                saveHtmlPage(currentUrl, doc);
                visitedUrls.add(currentUrl);

                if (currentDepth < maxDepth) {
                    Elements links = doc.select("a[href]");
                    for (Element link : links) {
                        String nextUrl = link.absUrl("href");
                        if (!visitedUrls.contains(nextUrl)) {
                            queue.add(new UrlDepthPair(nextUrl, currentDepth + 1));
                        }
                    }
                }
            } catch (IOException e) {
                System.err.println("Error fetching URL: " + currentUrl);
            }
        }
    }

    public void saveHtmlPage(String url, Document doc) {
        // Same as before...
    }

    public static void main(String[] args) {
        // Same as before...
    }

    private static class UrlDepthPair {
        String url;
        int depth;

        public UrlDepthPair(String url, int depth) {
            this.url = url;
            this.depth = depth;
        }
    }
}

        请确保你有合适的权限访问目标网站,并且遵守robots.txt文件中的爬虫规则及网站的服务条款。此外,应该添加合理的延迟(例如使用Thread.sleep)以避免对网站服务器造成不必要的负载。

        要完全遵守robots.txt的规则,你可能需要使用更完整的解决方案,如Google的google-robotstxt库或Apache的crawler-commons库,它们能够解析并遵守robots.txt文件的详细规则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

济南大飞哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值