Пример #1
0
  @Override
  public Links visitAndGetNextLinks(Page page) {
    System.out.println(page.getHtml());
    if (Pattern.matches(".*jpg$", page.getUrl())
        || Pattern.matches(".*png$", page.getUrl())
        || Pattern.matches(".*gif$", page.getUrl())) {
      try {
        FileUtils.writeFileWithParent(
            "download/" + id.incrementAndGet() + ".jpg", page.getContent());
        System.out.println("download:" + page.getUrl());
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    MyLinks nextLinks = new MyLinks();
    RegexRule rr = new RegexRule();
    rr.addRule(".*meishij.*");
    nextLinks.addAllFromDocument(page.getDoc(), rr);
    nextLinks.filterImgUrl(page.getDoc(), rr);

    System.out.println(nextLinks.size());
    try {
      Thread.sleep(1500);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return nextLinks;
  }
Пример #2
0
  @Override
  public Links visitAndGetNextLinks(Page page) {
    Document doc = page.getDoc();

    String html = page.getHtml();
    String title = doc.title();
    System.out.println("URL:" + page.getUrl() + "  关键字:" + getKeyword() + "  标题:" + title);
    Map<String, String> map = new HashMap<String, String>();
    map.put("url", page.getUrl());
    if (isExistKeywords(html)) {
      save(map);
    }

    /* 下面是2.0版本新加入的内容 */
    /*
     * 抽取page中的链接返回,这些链接会在下一轮爬取时被爬取。 不用担心URL去重,爬虫会自动过滤重复URL。
     */
    Links nextLinks = new Links();

    /*
     * 我们只希望抽取满足正则约束的URL, Links.addAllFromDocument为我们提供了相应的功能
     */
    nextLinks.addAllFromDocument(doc, regexRule);

    /*
     * Links类继承ArrayList<String>,可以使用add、addAll等方法自己添加URL
     * 如果当前页面的链接中,没有需要爬取的,可以return null
     * 例如如果你的爬取任务只是爬取seed列表中的所有链接,这种情况应该return null
     */
    return nextLinks;
  }
Пример #3
0
  @Override
  public void visit(Page page, CrawlDatums next) {

    String keyword = page.getMetaData("keyword");
    String pageType = page.getMetaData("pageType");
    if (pageType.equals("searchEngine")) {
      int pageNum = Integer.valueOf(page.getMetaData("pageNum"));
      System.out.println("成功抓取关键词" + keyword + "的第" + pageNum + "页搜索结果");
      Elements results = page.select("li.b_ans h2>a,li.b_algo h2>a");
      for (int rank = 0; rank < results.size(); rank++) {
        Element result = results.get(rank);

        /*
        我们希望继续爬取每条搜索结果指向的网页,这里统称为外链。
        我们希望在访问外链时仍然能够知道外链处于搜索引擎的第几页、第几条,
        所以将页号和排序信息放入后续的CrawlDatum中,为了能够区分外链和
        搜索引擎结果页面,我们将其pageType设置为outlink,这里的值完全由
        用户定义,可以设置一个任意的值

        在经典爬虫中,每个网页都有一个refer信息,表示当前网页的链接来源。
        例如我们首先访问新浪首页,然后从新浪首页中解析出了新的新闻链接,
        则这些网页的refer值都是新浪首页。WebCollector不直接保存refer值,
        但我们可以通过下面的方式,将refer信息保存在metaData中,达到同样的效果。
        经典爬虫中锚文本的存储也可以通过下面方式实现。
        */
        CrawlDatum datum =
            new CrawlDatum(result.attr("abs:href"))
                .putMetaData("keyword", keyword)
                .putMetaData("pageNum", pageNum + "")
                .putMetaData("rank", rank + "")
                .putMetaData("pageType", "outlink")
                .putMetaData("refer", page.getUrl());
        next.add(datum);
      }

    } else if (pageType.equals("outlink")) {
      int pageNum = Integer.valueOf(page.getMetaData("pageNum"));
      int rank = Integer.valueOf(page.getMetaData("rank"));
      String refer = page.getMetaData("refer");

      String line =
          String.format(
              "第%s页第%s个结果:%s(%s字节)\trefer=%s",
              pageNum, rank + 1, page.getDoc().title(), page.getContent().length, refer);
      System.out.println(line);
    }
  }
Пример #4
0
  @Override
  public Links visitAndGetNextLinks(Page page) {
    Document doc = page.getDoc();

    Links nextLinks = new Links();
    String url = page.getUrl();

    // 根分类,(家常菜谱 中华菜系 各地小吃 外国菜谱...)
    if (BASE_URL.equals(url)) {
      synchronized (mDishTypeList) {
        mDishTypeList.addAll(mParser.getPrimaryTypes(doc));

        int id = 1;
        for (DishType parentType : mDishTypeList) {
          nextLinks.add(parentType.url);
          parentType.id = id++;
          mUpdater.updateType(parentType);
        }
      }
    } else {
      // 子分类 (家常菜私家菜凉菜....)
      boolean isChildTypeUrl = false;
      synchronized (mDishTypeList) {
        for (DishType parentType : mDishTypeList) {

          if (url.equals(parentType.url)) {
            parentType.children = mParser.getChildrenTypes(doc);

            for (DishType child : parentType.children) {
              nextLinks.add(child.url);

              child.parentType = parentType;

              synchronized (mSubDishTypeUrlList) {
                mSubDishTypeUrlList.add(child);
              }
              mUpdater.updateType(child);
            }
            isChildTypeUrl = true;
            break;
          }
        }
      }

      if (!isChildTypeUrl) {

        // 子分类详情(为菜谱列表),用于获取菜谱详情
        boolean isSubDishTypeUrl = false;
        synchronized (mSubDishTypeUrlList) {
          for (DishType type : mSubDishTypeUrlList) {
            if (url.contains(type.url + "&page=")
                || url.contains(type.url + "?&page=")
                || url.equals(type.url)) {
              List<String> urls = mParser.getDishTypeDetailPageUrls(doc, url, url.equals(type.url));
              isSubDishTypeUrl = true;
              nextLinks.addAll(urls);
              break;
            }
          }
        }

        if (!isSubDishTypeUrl) {
          // 菜谱详情
          DishDetail detail = mParser.getDishDetail(doc, url);

          mUpdater.updateDishDetail(detail);
        }
      }
    }

    return nextLinks;
  }