ПРЕДИСЛОВИЕ: Прежде чем написать эту статью, я в основном прочитал несколько подобных стилей написания хлистого. Некоторые из них используют очереди, чтобы написать их, что кажется не очень интуитивно понятным. У некоторых есть только один запрос, а затем выполняют анализ страниц. Они вообще не встают автоматически. Это также называется Crawler? Поэтому я написал о простом густо, основанном на моих собственных идеях.
Алгоритм введение
Программа использует в своей идее алгоритм «Широкий первый», инициирует получение запросов на нераверсированные ссылки один за другим, а затем анализирует возвращенную страницу с регулярными выражениями, выводит новую ссылку, которая не была обнаружена, добавляет ее в коллекцию и пересекает ее в следующей петле.
Конкретная реализация использует карту <строка, Boolean>, а пары клавиш-это ссылка, и следует ли пересекать. В программе используются две коллекции карт, а именно: Oldmap и Newmap. Первоначальная ссылка находится в OldMap, и затем представлен запрос на ссылку с флагом False в OldMap, проанализируйте страницу и используйте регулярно для удаления ссылки под тегом <a>. Если эта ссылка не в Oldmap и Newmap, это означает, что это новая ссылка. В то же время, если эта ссылка является ссылкой целевого веб -сайта, который мы должны получить, мы поместим эту ссылку в NewMap и продолжим анализировать ее. Когда страница проанализирована, значение ссылки на текущей странице в OldMap установлено на True, что означает, что она была пройденна.
Наконец, когда вся ссылка, которая не была пересечена старой картой, была пересечена, если вы обнаружите, что Newmap не пуста, это означает, что в этом цикле были сгенерированы новые ссылки. Следовательно, эти новые ссылки добавляются в старую карту и продолжают рекурветно проходить. В противном случае это означает, что в этом цикле не было создано никаких новых ссылок. Если вы продолжите цикл, вы больше не можете генерировать новые ссылки. Поскольку задача закончена, коллекция ссылок старая карта будет возвращена.
Две программы реализация
Приведенные выше идеи были объяснены очень четко, и в ключевых областях кода есть комментарии, поэтому я не буду говорить об этом здесь, код выглядит следующим образом:
Действие пакета; импорт java.io.bufferedreader; import java.io.ioexception; import java.io.inputstream; import java.io.inputStreamReader; импорт java.net.httpurlConnection; импорт java.net.malformedurlexectement; импорт. java.util.map; import java.util.regex.matcher; import java.util.regex.pattern; открытый класс webcrawlerdemo {public static void main (string [] args) {webcrawlerdemo webcrawlerdemo = new WebRawlerDemo (); webcrawlerdemo.myprint ("http://www.zifangsky.cn"); } public void myprint (String baseurl) {map <string, boolean> oldmap = new LinkedHashmap <String, boolean> (); // Ссылка на хранение. // шаблон хоста p = pattern.compile ("(https?: //)? [^/// s]*"); // Например: http://www.zifangsky.cn matchter m = p.matcher (baseurl); if (m.find ()) {oldlinkhost = m.group (); } oldmap.put (baseurl, false); OldMap = crawllinks (Oldlinkhost, Oldmap); for (map.Entry <String, boolean> mapping: oldMap.EntrySet ()) {System.out.println ("Ссылка:" + mapping.getKey ()); }} /**. Получите запросы постоянно инициируются для новых ссылок, которые не были пересечены, пока полный набор не будет пройден. Это означает, что новые ссылки не могут быть найдены, а задача заканчивается * * @param oldlinkhost доменное имя, такое как: http://www.zifangsky.cn * @param oldmap Коллекция ссылок, которые должны пройти * * @return return all clawled link * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Map <string, boolean> newmap = new LinkedHashmap <String, boolean> (); String oldlink = ""; for (map.Entry <String, boolean> Mapping: oldMap.EntrySet ()) {System.out.println ("Ссылка:" + mapping.getKey () + "--------- Проверка:" + maping.getValue ()); // Если это не было прошел через (! Mapping.getValue ()) {oldlink = maping.getKey (); // инициировать запрос получить запрос try {url url = new URL (OldLink); Httpurlconnection connection = (httpurlconnection) url .openconcenection (); connection.setrequestmethod ("Get"); Connection.setConnecttimeout (2000); Connection.SetReadTimeOut (2000); if (connection.getResponsecode () == 200) {inputStream inputStream = connection.getInputStream (); BufferedReader Reader = New BufferedReader (New InputStreamReader (inputStream, "UTF-8")); String line = ""; Pattern Pattern = pattern .compile ("<a.*? Href = [/" ']? ((Https?: //)?/? [^/"']+) [/" ']? {String newlink = matcher.group (1) .trim (); OldLinkhost + "/" + Newlink; NewLink.StartSwith (OldLinkhost) {// System.out.println ("temp2:" + newlink); Thread.sleep (1000); } catch (прерванное искусство e) {e.printstacktrace (); } oldMap.Replace (OldLink, false, true); }} // Есть новая ссылка, продолжайте пройти через if (! Newmap.isempty ()) {oldmap.putall (newmap); OldMap.putall (Crawllinks (Oldlinkhost, Oldmap)); // Из-за характеристик карты не будет дублирования пар клавишных значений} return oldmap; }}Три последних результата теста
PS: Фактически, использование рекурсии не очень хорошо, потому что, если на веб -сайте больше страниц, потребление памяти будет очень большим, если программа будет работать в течение длительного времени.
Спасибо за чтение, я надеюсь, что это поможет вам. Спасибо за поддержку этого сайта!