서문 :이 기사를 작성하기 전에 주로 비슷한 크롤러 작문 스타일을 읽습니다. 그들 중 일부는 대기열을 사용하여 쓰기를 사용하여 직관적이지 않습니다. 일부는 하나의 요청 만 있고 페이지 분석을 수행합니다. 그들은 전혀 자동으로 일어나지 않습니다. 이것은 Crawler라고도합니다. 따라서 나는 내 아이디어를 바탕으로 간단한 크롤러에 대해 썼습니다.
알고리즘 소개
이 프로그램은 아이디어에서 폭 최초의 알고리즘을 사용하고, 트레이버되지 않은 링크에 대한 요청을 시작한 다음, 정규 표현식으로 반환 된 페이지를 구문 분석하고, 발견되지 않은 새 링크를 꺼내고, 컬렉션에 추가하고, 다음 루프에서이를 가로 웁니다.
특정 구현은 MAP <String, Boolean>을 사용하며 키 값 쌍은 링크 및 가로 질주할지 여부입니다. 이 프로그램에는 두 가지 맵 컬렉션, 즉 OldMap 및 NewMap이 사용됩니다. 초기 링크는 OldMap에 있으며 OldMap에서 FAGL FALSE와의 링크에 대한 요청이 이루어지고 페이지를 구문 분석하고 <a> 태그 아래 링크를 제거하는 데 정기적으로 사용합니다. 이 링크가 OldMap 및 NewMap에 있지 않으면 이것이 새로운 링크임을 의미합니다. 동시에,이 링크가 얻어야 할 대상 웹 사이트의 링크 인 경우이 링크를 NewMap에 넣고 계속 구문 분석합니다. 페이지가 구문 분석되면 OldMap의 현재 페이지의 링크 값이 true로 설정되어있어 트래버스되었음을 의미합니다.
마지막으로, OldMap에 의해 통과되지 않은 전체 링크가 횡단되었을 때, NewMap이 비어 있지 않다는 것을 알게되면이 루프에서 새 링크가 생성되었음을 의미합니다. 따라서 이러한 새로운 링크는 OldMap에 추가되어 계속해서 재귀 적으로 통과합니다. 그렇지 않으면이 루프에서 새로운 링크가 생성되지 않았 음을 의미합니다. 루프를 계속하면 더 이상 새 링크를 생성 할 수 없습니다. 작업이 끝나기 때문에 링크 컬렉션 OldMap이 반환됩니다.
두 개의 프로그램 구현
위의 관련 아이디어는 매우 명확하게 설명되었으며 코드의 주요 영역에 의견이 있으므로 여기서는 이야기하지 않으므로 코드는 다음과 같습니다.
패키지 조치; import java.io.bufferedReader; import java.io.ioException; import java.io.inputStream; import java.io.inputStreamReader; import java.net.httpurlconnection; import java.net.malformedurlexcection; import java.net.url; java.util.map; import java.util.regex.matcher; import java.util.regex.pattern; public class webcrawlerdemo {public static void main (string [] args) {webcrawlerdemo webcrawlerdemo = new WebCrawlerdemo (); webcrawlerdemo.myprint ( "http://www.zifangsky.cn"); } public void myprint (String baseurl) {map <string, boolean> oldmap = new LinkedHashMap <String, boolean> (); // 스토리지 링크는 트래버스됩니다. // 키 값 쌍 String OldLinkHost = ""; // 호스트 패턴 p = pattern.compile ( "(https? : //)? [^// s]*"); // 예 : http://www.zifangsky.cn 경기자 m = p.matcher (baseurl); if (m.find ()) {OldLinkHost = m.group (); } oldmap.put (baseurl, false); OldMap = crawllinks (OldLinkhost, OldMap); for (map.entry <string, boolean> 매핑 : OldMap.entryset ()) {system.out.println ( "링크 :" + mapping.getKey ()); }} /*** 웹 사이트에서 크롤링 할 수있는 모든 웹 페이지 링크를 크롤링하고 아이디어에서 폭 넓은 우선 순위 알고리즘을 사용하십시오. 완전한 세트가 가로 질 때까지 가로지 않은 새 링크에 대한 GET 요청은 지속적으로 시작됩니다. 이것은 새로운 링크를 찾을 수없고 작업이 끝나는 것을 의미합니다. * * @param oldlinkhost 도메인 이름 : http://www.zifangsky.cn * @param oldmap 트래버스 링크 모음 * * @return은 모든 크롤링 링크 컬렉션을 반환 */private map <string, boolean> crawllinks (string <string, boolean) <string <string <string <string <string. Map <String, boolean> newMap = New LinkedHashMap <String, boolean> (); 문자열 oldlink = ""; for (map.Entry <string, boolean> 매핑 : OldMap.entryset ()) {System.out.println ( "링크 :" + mapping.getKey () + "------- 확인 :" + mapping.getValue ()); // (! mapping.getValue ()) {OldLink = mapping.getKey (); // GET 요청을 시작합니다. {url url = new URL (OldLink); httpurlConnection Connection = (httpurlConnection) url .openConnection (); 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")); 문자열 line = ""; 패턴 패턴 = 패턴 .compile ( "<a.*? href = [/" ']? ((https? : //)?/? {string newlink = group (1) .trim (); Oldlinkhost + "/" + Newlink;} ridge // if (newlink.endswith ( "/"))). newlink.startswith (OldLinkHost) {// System.out.println ( " + NewLink. Thread.sleep (1000); } catch (InterruptedException e) {e.printstacktrace (); } OldMap.replace (OldLink, False, True); }} // 새 링크가 있습니다. (! newMap.isempty ()) {OldMap.putAll (newMap); OldMap.putAll (crawllinks (OldLinkhost, OldMap)); // 맵의 특성으로 인해 중복 키 값 쌍이 없습니다} return OldMap; }}세 가지 최종 테스트 결과
추신 : 사실, 웹 사이트에 더 많은 페이지가 있으면 프로그램이 오랫동안 실행되면 메모리 소비가 매우 커질 것이기 때문에 재귀 사용은 그리 좋지 않습니다.
읽어 주셔서 감사합니다. 도움이되기를 바랍니다. 이 사이트를 지원 해주셔서 감사합니다!