@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; }
@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; }
@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); } }
@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; }