ivolff

SimpleWebCrawler

Dec 25th, 2017
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.79 KB | None | 0 0
  1. package crawler;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.lang.reflect.Field;
  8. import java.net.URL;
  9. import java.util.*;
  10. import java.util.regex.Matcher;
  11. import java.util.regex.Pattern;
  12.  
  13. public class SimpleWebCrawler implements WebCrawler {
  14.  
  15.     private Downloader downloader;
  16.     private Map<String, Page> pages = new HashMap<>();
  17.     private Map<String, Image> images = new HashMap<>();
  18.     private List<String> hasOriginal = new ArrayList<>();
  19.  
  20.     public SimpleWebCrawler(Downloader downloader) {
  21.         this.downloader = new URLDownloader(downloader);
  22.     }
  23.  
  24.     @Override
  25.     public Page crawl(String url, int depth) throws IOException {
  26.         depth--;
  27.         url = decodeEntities(url);
  28.         InputStream inputStream;
  29.         try {
  30.             inputStream = this.downloader.download(url);
  31.         } catch (IOException ioe) {
  32.             System.out.println(ioe);
  33.             return getPage(url);
  34.         }
  35.  
  36.         Scanner s = new Scanner(inputStream).useDelimiter("\\A");
  37.         String content = s.hasNext() ? s.next() : "";
  38.  
  39.         String title = getTitleFromHTML(content);
  40.  
  41.         Page page = getPage(url, title);
  42.  
  43.         List<String> images = getImagesFromHTML(content);
  44.         for (String image : images) {
  45.             String[] res = doUrl(url, image);
  46.             InputStream is = new URL(res[0]).openStream();
  47.  
  48.             String[] parts = image.split("/");
  49.             String last_part = parts[parts.length-1];
  50.  
  51.             FileOutputStream fos = new FileOutputStream(last_part);
  52.  
  53.             byte[] buffer = new byte[8 * 1024];
  54.             int bytesRead;
  55.             while ((bytesRead = is.read(buffer)) != -1) {
  56.                 fos.write(buffer, 0, bytesRead);
  57.             }
  58.             is.close();
  59.             fos.close();
  60.  
  61.             page.addImage(getImage(res[0], last_part));
  62.         }
  63.  
  64.         List<String> links = getLinksFromHTML(content);
  65.  
  66.         for (String origLink : links) {
  67.             int pos = content.indexOf(origLink);
  68.             if (content.charAt(pos-1) == ' ' &&
  69.                     content.charAt(pos-2) == '-' &&
  70.                     content.charAt(pos-3) == '-' &&
  71.                     content.charAt(pos-4) == '!' &&
  72.                     content.charAt(pos-5) == '<') {
  73.                 continue;
  74.             }
  75.  
  76.             String link = getUrl(origLink);
  77.             String[] res = doUrl(url, link);
  78.             link = res[0];
  79.             String original = res[1];
  80.  
  81.             try {
  82.                 String urlTitle = getUrlTitle(origLink);
  83.                 original = original+urlTitle;
  84.             } catch (IllegalStateException e) {
  85.             }
  86.  
  87.             try {
  88.                 String urlTarget = getUrlTarget(origLink);
  89.                 original = original+urlTarget;
  90.             } catch (IllegalStateException e) {
  91.             }
  92.  
  93.             if (depth > 0) {
  94.                 if (!original.equals(link))
  95.                     page.addLink(this.crawl(link, depth));
  96.                 else {
  97.                     this.addLink(page, this.crawl(link, depth));
  98.                 }
  99.             } else {
  100.                 if (!original.equals(link))
  101.                     page.addLink(getPage(link));
  102.                 else {
  103.                     this.addLink(page, getPage(link));
  104.                 }
  105.             }
  106.         }
  107.         return page;
  108.     }
  109.  
  110.     private String[] doUrl(String url, String link) {
  111.         String original = link;
  112.         link = link.replace(" ", "");
  113.         String[] parts = url.split("/");
  114.         String last_part = parts[parts.length-1];
  115.  
  116.         if (link.startsWith("#")) {
  117.             link = url;
  118.             original = link+"#";
  119.         } else if (link.contains("#")) {
  120.             link = link.split("#")[0];
  121.             original = link+"#";
  122.         }
  123.  
  124.         if (!link.startsWith("http") && !link.startsWith("https")) { // absolute link
  125.             String url_part;
  126.             if (url.contains(".html") || url.contains(".zip") || url.contains(".xhtml")) {
  127.                 url_part = url.replace(last_part, "");
  128.             } else {
  129.                  url_part = url.replace(last_part + "/", "");
  130.             }
  131.             if (link.startsWith("../")) {
  132.                 int i = (url.contains(".html") || url.contains(".zip") || url.contains(".xhtml")) ? 2 : 1;
  133.                 while (link.indexOf("../") == 0) {
  134.                     link = link.substring(3, link.length());
  135.                     url_part = url_part.replace(parts[parts.length - i] + "/", "");
  136.                     i++;
  137.                 }
  138.                 link = url_part + link;
  139.             } else if (link.equals("..")) {
  140.                 link = url_part.replace(parts[parts.length - 1] + "/", "");
  141.             } else if (link.startsWith("//")) {
  142.                 link = "http:"+link;
  143.             } else if (link.startsWith("/")) {
  144.                 link = parts[0]+"//"+parts[2]+link;
  145.             } else {
  146.                 if (url.contains(".html") || url.contains(".zip") || url.contains(".xhtml")) {
  147.                     link = url_part + link;
  148.                     original = url_part + original;
  149.                 } else {
  150.                     link = url + link;
  151.                     original = url + original;
  152.                 }
  153.             }
  154.         }
  155.  
  156.         return new String[] {link, original};
  157.     }
  158.  
  159.     private String getTitleFromHTML(String html) {
  160.         Pattern p = Pattern.compile("<title>(.*?)</title>");
  161.         Matcher m = p.matcher(html);
  162.         m.find();
  163.         return m.group(1);
  164.     }
  165.  
  166.     private List<String> getLinksFromHTML(String html) {
  167.         List<String> links = new ArrayList<>();
  168.         Pattern p = Pattern.compile("<a.*?href.*?=.*?\"(.*?)\".*?>", Pattern.DOTALL);
  169.         Matcher m = p.matcher(html);
  170.         while(m.find()) {
  171.             links.add(m.group(0));
  172.         }
  173.         return links;
  174.     }
  175.  
  176.     private String getUrl(String url) {
  177.         Pattern p = Pattern.compile("<a.*?href.*?=.*?\"(.*?)\".*?>", Pattern.DOTALL);
  178.         Matcher m = p.matcher(url);
  179.         m.find();
  180.         return m.group(1);
  181.     }
  182.  
  183.     private String getUrlTitle(String url) throws IllegalStateException {
  184.         Pattern p = Pattern.compile("title=\"(.*?)\"", Pattern.DOTALL);
  185.         Matcher m = p.matcher(url);
  186.         m.find();
  187.         return m.group(1);
  188.     }
  189.  
  190.     private String getUrlTarget(String url) throws IllegalStateException {
  191.         Pattern p = Pattern.compile("target=\"(.*?)\"", Pattern.DOTALL);
  192.         Matcher m = p.matcher(url);
  193.         m.find();
  194.         return m.group(1);
  195.     }
  196.  
  197.     private List<String> getImagesFromHTML(String html) {
  198.         List<String> images = new ArrayList<>();
  199.         Pattern p = Pattern.compile("<img.*?src.*?=.*?\"(.*?)\".*?>", Pattern.DOTALL);
  200.         Matcher m = p.matcher(html);
  201.         while(m.find()) {
  202.             images.add(m.group(1));
  203.         }
  204.         return images;
  205.     }
  206.  
  207.     private Page getPage(String url, String title) {
  208.         url = decodeEntities(url.replace(" ", ""));
  209.         title = decodeEntities(title);
  210.         if (this.pages.containsKey(url)) {
  211.             Page p = this.pages.get(url);
  212.             if (p.getTitle().equals("") && !title.equals("")) {
  213.                 try {
  214.                     Field f = p.getClass().getDeclaredField("title");
  215.                     f.setAccessible(true);
  216.                     f.set(p, title);
  217.                 } catch (Exception e) {
  218.                     e.printStackTrace();
  219.                 }
  220.             }
  221.             return p;
  222.         } else {
  223.             this.pages.put(url, new Page(url, title));
  224.             return this.pages.get(url);
  225.         }
  226.     }
  227.  
  228.     private Page getPage(String url) {
  229.         return getPage(url, "");
  230.     }
  231.  
  232.     private Image getImage(String url, String file) {
  233.         url = decodeEntities(url);
  234.         if (this.images.containsKey(url)) {
  235.             return this.images.get(url);
  236.         } else {
  237.             this.images.put(url, new Image(url, file));
  238.             return this.images.get(url);
  239.         }
  240.     }
  241.  
  242.     private void addLink(Page p1, Page p2) {
  243.         if (!hasOriginal.contains(p2.getUrl())) {
  244.             hasOriginal.add(p2.getUrl());
  245.             p1.addLink(p2);
  246.             return;
  247.         }
  248.         if(!p1.getLinks().contains(p2)) {
  249.             p1.addLink(p2);
  250.         }
  251.         if(p2.getUrl().endsWith(".zip") || p2.getUrl().endsWith(".rar") || p2.getUrl().endsWith(".pdf")) {
  252.             p1.addLink(p2);
  253.         }
  254.     }
  255.  
  256.     private String decodeEntities(String html) {
  257.         html = html.replace("&lt;", "<");
  258.         html = html.replace("&gt;", ">");
  259.         html = html.replace("&amp;", "&");
  260.         html = html.replace("&mdash;", "—");
  261.         html = html.replace("&nbsp;", " ");
  262.         html = html.replace("\r\n", "");
  263.         return html;
  264.     }
  265. }
Advertisement
Add Comment
Please, Sign In to add comment