一个简单的java爬虫框架(java爬虫框架排行)

发布时间:2022-11-16

本文目录一览:

  1. java 实现网络爬虫用哪个爬虫框架比较好
  2. java 网络爬虫怎么实现
  3. java爬虫框架都有什么?哪个比较好学易用?谢谢!知道有nutch和heritrix可以,但是学习

java 实现网络爬虫用哪个爬虫框架比较好

有些人问,开发网络爬虫应该选择 Nutch、Crawler4j、WebMagic、Scrapy、WebCollector 还是其他的?这里按照我的经验随便扯淡一下: 上面说的爬虫,基本可以分 3 类:

  1. 分布式爬虫:Nutch
  2. Java 单机爬虫:Crawler4j、WebMagic、WebCollector
  3. 非 Java 单机爬虫:Scrapy

第一类:分布式爬虫

爬虫使用分布式,主要是解决两个问题:

  1. 海量 URL 管理
  2. 网速
    现在比较流行的分布式爬虫是 Apache 的 Nutch。但是对于大多数用户来说,Nutch 是这几类爬虫里最不好的选择,理由如下:
  3. Nutch 是为搜索引擎设计的爬虫,大多数用户是需要一个做精准数据爬取(精抽取)的爬虫。Nutch 运行的一套流程里,有三分之二是为了搜索引擎而设计的。对精抽取没有太大的意义。也就是说,用 Nutch 做数据抽取,会浪费很多时间在不必要的计算上。如果你试图通过对 Nutch 进行二次开发,来使得它适用于精抽取的业务,基本上就要破坏 Nutch 的框架,把 Nutch 改得面目全非,有修改 Nutch 的能力,不如自己重新写一个分布式爬虫框架。
  4. Nutch 依赖 Hadoop 运行,Hadoop 本身会消耗很多时间。如果集群机器数量较少,爬取速度反而不如单机爬虫快。
  5. Nutch 的插件系统蹩脚。利用反射机制加载和调用插件,使得程序编写和调试都变得异常困难。Nutch 并没有为精抽取提供相应的插件挂载点。大多数 Nutch 的精抽取插件,都是挂载在“页面解析”(parser) 这个挂载点的,这个挂载点其实是为了解析链接(为后续爬取提供 URL),以及为搜索引擎提供一些易抽取的网页信息(网页的 meta 信息、text 文本)。
  6. Nutch 的二次开发成本高。爬虫的编写和调试所需的时间,往往是单机爬虫所需的十倍不止。了解 Nutch 源码的学习成本很高,何况是要让一个团队的人都读懂 Nutch 源码。调试过程中会出现除程序本身之外的各种问题(Hadoop 的问题、HBase 的问题)。
  7. Nutch2 的持久化数据误解。很多人其实理解错了,这里说的持久化数据是指将 URL 信息(URL 管理所需要的数据)存放到 Avro、HBase、MySQL,并不是你要抽取的结构化数据。其实对大多数人来说,URL 信息存在哪里无所谓。
  8. Nutch2 的版本目前并不适合开发。官方现在稳定的 Nutch 版本是 nutch2.2.1,但是这个版本绑定了 gora-0.3。如果想用 HBase 配合 Nutch(大多数人用 nutch2 就是为了用 HBase),只能使用 0.90 版本左右的 HBase,相应的就要将 Hadoop 版本降到 hadoop 0.2 左右。而且 nutch2 的官方教程比较有误导作用。 所以,如果你不是要做搜索引擎,尽量不要选择 Nutch 作为爬虫。有些团队就喜欢跟风,非要选择 Nutch 来开发精抽取的爬虫,其实是冲着 Nutch 的名气(Nutch 作者是 Doug Cutting),当然最后的结果往往是项目延期完成。 如果你是要做搜索引擎,Nutch1.x 是一个非常好的选择。Nutch1.x 和 Solr 或者 ES 配合,就可以构成一套非常强大的搜索引擎了。如果非要用 Nutch2 的话,建议等到 Nutch2.3 发布再看。目前的 Nutch2 是一个非常不稳定的版本。

java 网络爬虫怎么实现

网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。 传统爬虫从一个或若干初始网页的 URL 开始,获得初始网页上的 URL,在抓取网页的过程中,不断从当前页面上抽取新的 URL 放入队列,直到满足系统的一定停止条件。对于垂直搜索来说,聚焦爬虫,即有针对性地爬取特定主题网页的爬虫,更为适合。 以下是一个使用 Java 实现的简单爬虫核心代码:

public void crawl() throws Throwable {
    while (continueCrawling()) {
        CrawlerUrl url = getNextUrl(); // 获取待爬取队列中的下一个 URL
        if (url != null) {
            printCrawlInfo();
            String content = getContent(url); // 获取 URL 的文本信息
            // 聚焦爬虫只爬取与主题内容相关的网页,这里采用正则匹配简单处理
            if (isContentRelevant(content, this.regexpSearchPattern)) {
                saveContent(url, content); // 保存网页至本地
                // 获取网页内容中的链接,并放入待爬取队列中
                Collection urlStrings = extractUrls(content, url);
                addUrlsToUrlQueue(url, urlStrings);
            } else {
                System.out.println(url + " is not relevant ignoring ...");
            }
            // 延时防止被对方屏蔽
            Thread.sleep(this.delayBetweenUrls);
        }
    }
    closeOutputStream();
}
private CrawlerUrl getNextUrl() throws Throwable {
    CrawlerUrl nextUrl = null;
    while ((nextUrl == null) && (!urlQueue.isEmpty())) {
        CrawlerUrl crawlerUrl = this.urlQueue.remove();
        // doWeHavePermissionToVisit:是否有权限访问该 URL,友好的爬虫会根据网站提供的 "Robot.txt" 中配置的规则进行爬取
        // isUrlAlreadyVisited:URL 是否访问过,大型的搜索引擎往往采用 BloomFilter 进行排重,这里简单使用 HashMap
        // isDepthAcceptable:是否达到指定的深度上限。爬虫一般采取广度优先的方式。一些网站会构建爬虫陷阱(自动生成一些无效链接使爬虫陷入死循环),采用深度限制加以避免
        if (doWeHavePermissionToVisit(crawlerUrl)
                && (!isUrlAlreadyVisited(crawlerUrl))
                && isDepthAcceptable(crawlerUrl)) {
            nextUrl = crawlerUrl;
            // System.out.println("Next url to be visited is " + nextUrl);
        }
    }
    return nextUrl;
}
private String getContent(CrawlerUrl url) throws Throwable {
    // HttpClient4.1 的调用与之前的方式不同
    HttpClient client = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet(url.getUrlString());
    StringBuffer strBuf = new StringBuffer();
    HttpResponse response = client.execute(httpGet);
    if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(entity.getContent(), "UTF-8"));
            String line = null;
            if (entity.getContentLength() > 0) {
                strBuf = new StringBuffer((int) entity.getContentLength());
                while ((line = reader.readLine()) != null) {
                    strBuf.append(line);
                }
            }
        }
        if (entity != null) {
            entity.consumeContent();
        }
    }
    // 将 url 标记为已访问
    markUrlAsVisited(url);
    return strBuf.toString();
}
public static boolean isContentRelevant(String content, Pattern regexpPattern) {
    boolean retValue = false;
    if (content != null) {
        // 是否符合正则表达式的条件
        Matcher m = regexpPattern.matcher(content.toLowerCase());
        retValue = m.find();
    }
    return retValue;
}
public List extractUrls(String text, CrawlerUrl crawlerUrl) {
    Map urlMap = new HashMap();
    extractHttpUrls(urlMap, text);
    extractRelativeUrls(urlMap, text, crawlerUrl);
    return new ArrayList(urlMap.keySet());
}
private void extractHttpUrls(Map urlMap, String text) {
    Matcher m = (text);
    while (m.find()) {
        String url = m.group();
        String[] terms = url.split("a href=\"");
        for (String term : terms) {
            // System.out.println("Term = " + term);
            if (term.startsWith("http")) {
                int index = term.indexOf("\"");
                if (index > 0) {
                    term = term.substring(0, index);
                }
                urlMap.put(term, term);
                System.out.println("Hyperlink: " + term);
            }
        }
    }
}
private void extractRelativeUrls(Map urlMap, String text, CrawlerUrl crawlerUrl) {
    Matcher m = relativeRegexp.matcher(text);
    URL textURL = crawlerUrl.getURL();
    String host = textURL.getHost();
    while (m.find()) {
        String url = m.group();
        String[] terms = url.split("a href=\"");
        for (String term : terms) {
            if (term.startsWith("/")) {
                int index = term.indexOf("\"");
                if (index > 0) {
                    term = term.substring(0, index);
                }
                String s = "http://" + host + term;
                urlMap.put(s, s);
                System.out.println("Relative url: " + s);
            }
        }
    }
}
public static void main(String[] args) {
    try {
        String url = "";
        Queue urlQueue = new LinkedList();
        String regexp = "java";
        urlQueue.add(new CrawlerUrl(url, 0));
        NaiveCrawler crawler = new NaiveCrawler(urlQueue, 100, 5, 1000L, regexp);
        // boolean allowCrawl = crawler.areWeAllowedToVisit(url);
        // System.out.println("Allowed to crawl: " + url + " " + allowCrawl);
        crawler.crawl();
    } catch (Throwable t) {
        System.out.println(t.toString());
        t.printStackTrace();
    }
}

java爬虫框架都有什么?哪个比较好学易用?谢谢!知道有nutch和heritrix可以,但是学习

登录的,建议你用 Jsoup 带着 cookie 进去。 动态的,建议你用 HtmlUnit。 WebMagic 和 Jsoup 都很好学。有时间学学,虽然不是必会,但是这种小工具说不定什么时候就用得上。