자바 로 간단하게 웹 매 직 을 오 르 는 법 을 알려 드릴 게 요.

자바 파충류-WebMagic
 1.1 WebMagic 전체 구성 도
WebMagic总体架构图
1.2 WebMagic 핵심 구성 요소
1.2.1 Downloader
이 구성 요 소 는 인터넷 에서 페이지 를 다운로드 하 는 것 을 책임 진다.웹 매 직 은 기본적으로 다운로드 도구 로 사용Apache HttpClient합 니 다.
1.2.2 PageProcessor
이 구성 요 소 는 페이지 를 분석 하고 우리 의 업무 에 따라 정 보 를 추출 합 니 다.웹 매 직 은 HTML 분석 도구 로 Jsoup 을 사용 하고 이 를 바탕 으로 Xpath 를 분석 하 는 도구 Xsoup 을 개발 했다.
1.2.3 Scheduler
이 구성 요 소 는 캡 처 할 URL 과 무 거 운 작업 을 관리 합 니 다.WebMagic 은 기본적으로 JDK 메모리 큐 관리 URL 을 사용 하고 집합 을 통 해 무 게 를 제거 합 니 다.
Redis 를 사용 하여 분산 관 리 를 지원 합 니 다.
1.2.4 Pipeline
이 구성 요 소 는 추출 결과 의 처 리 를 책임 집 니 다.계산,파일,데이터 베이스 등 을 포함 합 니 다.
1.2.5 데이터 유통 대상
 1. RequestRequestURL 주소 에 대한 패키지 입 니 다.하나의 Request 는 URL 주소 에 대응 합 니 다.
이것 은 PageProcessor 와 Downloader 가 상호작용 하 는 캐리어 이자 PageProcessor 가 Downloader 를 제어 하 는 유일한 방식 이다.
URL 자 체 를 제외 하고 키-Value 구조의 필드extra도 포함 되 어 있 습 니 다.extra 에 특수 한 속성 을 저장 한 다음 다른 곳 에서 읽 어서 다른 기능 을 수행 할 수 있 습 니 다.예 를 들 어 이전 페이지 의 일부 정 보 를 추가 하 는 등 이다.
2. PagePage다운 로 더 에서 다운로드 한 페이지 인 HTML 일 수도 있 고 JSON 또는 다른 텍스트 형식의 내용 일 수도 있 습 니 다.
페이지 는 웹 매 직 추출 과정의 핵심 대상 으로 추출,결과 저장 등 방법 을 제공 합 니 다.
3. ResultItemsResultItems는 하나의 Map 에 해당 하 며,바 텀 은LinkedHashMap을 사용 하여 저장 되 며,PageProcessor 처리 결 과 를 저장 하여 Pipeline 에 사용 하도록 한다.API 는 Map 과 유사 합 니 다.주의해 야 할 것 은 필드skip가 있 습 니 다.true 로 설정 하면 Pipeline 에 의 해 처리 되 지 않 고 건 너 뛰 는 것 입 니 다.
1.2.6 Spider―WebMagic 핵심 엔진
스파이 더 는 웹 매 직 내부 프로 세 스 의 핵심 이다.Downloader,PageProcessor,Scheduler,Pipeline 은 모두 Spider 의 한 속성 으로 이 속성 들 은 자 유 롭 게 설정 할 수 있 으 며 이 속성 을 설정 하면 서로 다른 기능 을 실현 할 수 있다.스파이 더 는 파충류 의 생 성,작 동,정지,다 중 스 레 드 등 기능 을 봉인 한 웹 매 직 작업 의 입구 이기 도 하 다.
1.3 연습 데모
수 요 는 샤 먼 제한 문장 을 얻 는 것 이다.글 의 출처:http://xm.bendibao.com/traffic/2018116/54311.shtm구체 적 인 수 요 는 다음 과 같다.
1.글 의 하이퍼링크 삭제
2.글 의 그림 을 로 컬 로 다운로드
3.글 끝 삭제: ...1.3.1 맞 춤 형 다운 로 더
페이지 의 실 효 를 예방 하기 위해 링크 주소 가 존재 하지 않 을 때 로 그 를 인쇄 합 니 다.

public class MyHttpClientDownloader extends HttpClientDownloader {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     *          
     */
    @Override
    protected Page handleResponse(Request request, String charset, HttpResponse httpResponse, Task task) throws IOException {
        Page page = super.handleResponse(request, charset, httpResponse, task);
        if(httpResponse.getStatusLine().getStatusCode()!= ConstantsField.PAGE_STATUS_200){
            page.setDownloadSuccess(false);
            logger.warn("         ,    !");
        }
        return page;
    }
}
1.3.2 맞 춤 형 PageProcessor
이 페이지 프로 세 서 는 페이지 추출 을 실현 하여 위의 요구 에 부합 한다.
처 리 된 데 이 터 를 추가 합 니 다:Downloader대상,그리고 설정 키 는 각각:PageimgList입 니 다.

public class XmPageProcessor implements PageProcessor {

    /**
     *          ,    、    、     
     */
    private Site site = Site.me().setCycleRetryTimes(3).setSleepTime(1000);

    /**
     *   :      
     */
    @Override
    public void process(Page page) {
        //         
        Selectable selectable = page.getHtml().css(ConstantsField.PAGE_CSS_CONTENT);

        //    
        List<String> pImgList = selectable.xpath(ConstantsField.XPATH_IMG).all();
        List<String> imgUrl = new ArrayList<>();
        if(pImgList.size()>0){
            Pattern compile = Pattern.compile(ConstantsField.REX_IMG_SRC);
            for (String img : pImgList) {
                Matcher matcher = compile.matcher(img);
                while (matcher.find()){
                    imgUrl.add(matcher.group(1));
                }
            }
        }
        if(imgUrl.size()>0){
            page.putField("imgList",imgUrl);
        }else {
            page.putField("imgList",null);
        }

        //      StringBuilder
        String content = selectable.toString();
        StringBuilder stringBuilder = new StringBuilder(content);

        //     
        StringBuilder newString = dealLink(stringBuilder);

        //    
        int startIndex = newString.indexOf(ConstantsField.END_CONTENT);
        if(startIndex>0) {
            newString.delete(startIndex, stringBuilder.length());
            newString.append("</div>");
        }

        page.putField("content",newString.toString());
    }

    @Override
    public Site getSite() {
        return site;
    }

    /**
     *      
     */
    private static StringBuilder dealLink(StringBuilder stringBuilder){
        StringBuilder newString = new StringBuilder(stringBuilder);
        int aIndex = newString.indexOf("<a href");
        while (aIndex != -1){
            int pStart = newString.lastIndexOf("<p>", aIndex);
            int pEnd = (newString.indexOf("</p>", aIndex) + 4);
            newString.delete(pStart,pEnd);
            aIndex = newString.indexOf("<a href");
        }
        return newString;
    }
}
1.3.3 맞 춤 형 파이프라인content결 과 를 처리 하 는 곳 입 니 다.여기 서 우 리 는 결 과 를 저장 하 는 파일 을 처리 합 니 다.사이트 텍스트 는Pipeline형식 으로 저장 되 고 이미지 텍스트 는 사이트 소스 파일 의 형식 으로 저장 된다.

public class MyFilePipeline extends FilePersistentBase implements Pipeline {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private StringBuilder filepath;

    private MyFilePipeline() {
        this.setPath(ConstantsField.DEFAULT_SAVE_LOCATION);
    }

    public MyFilePipeline(String path) {
        if(path!=null){
            this.setPath(path);
        }else {
            new MyFilePipeline();
        }
        filepath = new StringBuilder().append(this.path).
                append(PATH_SEPERATOR).append(ConstantsField.FILE_NAME)
                .append(ConstantsField.FILE_POSTFIX);

    }

    @Override
    public void process(ResultItems resultItems, Task task) {
        //      
        try(PrintWriter printWriter = new PrintWriter(new FileWriter(getFile(filepath.toString()),false))) {
            printWriter.write(resultItems.get("content").toString());
            logger.info("      ,     :"+filepath);

            //    
            List<String> imgList = resultItems.get("imgList");
            if(imgList!=null&&imgList.size()>0){
                boolean dowload = DownloadImgUtils.download(imgList, this.getPath());
                if(dowload){
                    logger.info("      ,     :" + this.getPath());
                }
            }

        } catch (IOException e) {
            logger.error("      :" + e.getCause().toString());
        }
    }
}
여기 서 웹 페이지 는stm형식 과 이미지 저장 을 실 현 했 고 이미지 저장 은 다음 과 같은 도구 류stm를 사용 했다.

public class DownloadImgUtils {

    /**
     *     
     * @param imgList     
     * @param savePath     
     * @return     true
     */
    public static boolean download(List<String> imgList, String savePath) throws IOException {
        URL url;
        DataInputStream dataInputStream = null;
        FileOutputStream fileOutputStream = null;
        File file;
        try {
            for (String imgUrl : imgList) {
                //     
                Pattern pat=Pattern.compile(ConstantsField.REX_IMG_SUFFIX);
                Matcher mc=pat.matcher(imgUrl);
                while(mc.find()) {
                    String fileName= mc.group();
                    file = new File(savePath + fileName);
                    file.createNewFile();
                    fileOutputStream = new FileOutputStream(savePath + fileName);
                }

                url = new URL(imgUrl);
                dataInputStream = new DataInputStream(url.openStream());

                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int length;
                while ((length = dataInputStream.read(buffer))>0){
                    outputStream.write(buffer,0,length);
                }
                fileOutputStream.write(outputStream.toByteArray());
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            dataInputStream.close();
            fileOutputStream.close();
        }

        return false;
    }
}
1.3.4 시작 클래스

public class WebMagicApplication {

    private String url;
    private String saveUrl;

    /**
     *          
     */
    public WebMagicApplication() {
        this.url = ConstantsField.XM_BDB_URL;
        this.saveUrl = ConstantsField.DEFAULT_SAVE_LOCATION;
    }

    public WebMagicApplication(String url, String saveUrl) {
        this.url = url;
        this.saveUrl = saveUrl;
    }

    public void start(){
        Spider.create(new XmPageProcessor()).addUrl(this.url).addPipeline(new MyFilePipeline(this.saveUrl)).setDownloader(new MyHttpClientDownloader()).run();
    }

    public static void main(String[] args) {
        WebMagicApplication webMagicApplication = new WebMagicApplication("http://xm.bendibao.com/traffic/2018116/5431122.shtm","C:\\");
        webMagicApplication.start();
    }
}
여기 서 시작 클래스 는 파 라 메 트릭 구조 나 파 라 메 트릭 구 조 를 사용 할 수 있 습 니 다.파 라 메 트릭 구 조 는 기본적으로 URL 과 저장 주 소 를DownloadImgUtils클래스 의ConstantsField속성 과XM_BDB_URL로 사용 합 니 다.
연습 중의DEFAULT_SAVE_LOCATION구체 적 으로 다음 과 같다.

public final class ConstantsField {
    /**
     *    CSS   
     */
    public static final String PAGE_CSS_CONTENT = "div.content";

    /**
     *         
     */
    public static final String END_CONTENT = "<div id=\"adInArticle\"></div>";

    /**
     *      URL
     */
    public static final String XM_BDB_URL = "http://xm.bendibao.com/traffic/2018116/54311.shtm";

    /**
     *         
     */
    public static final String DEFAULT_SAVE_LOCATION = "C:\\";

    /**
     *    
     */
    public static final String FILE_NAME = "2021        (    )";

    /**
     *     
     */
    public static final String FILE_POSTFIX = ".stm";

    /**
     *        
     */
    public static final int PAGE_STATUS_200 = 200;

    /**
     *     src
     */
    public static final String REX_IMG_SRC = "src\\s*=\\s*\"?(.*?)(\"|>|\\s+)";

    /**
     *         
     */
    public static final String REX_IMG_SUFFIX = "[\\w]+[\\.](jpeg|jpg|png)";

    /**
     *     XPATH
     */
    public static final String XPATH_IMG = "//*[@id=\"bo\"]/*/img";
}
1.3.5 소스 주소
연습 데모 소스 주소:https://gitee.com/Xiaoxinnolabi/web-magic/settings
WebMagic 중국어 문서:http://webmagic.io/docs/zh/
WebMagic 소스 주소:https://github.com/code4craft/webmagic/
자바 로 간단하게 웹 매 직 을 오 르 는 방법 을 알려 드 리 는 이 글 은 여기까지 입 니 다.더 많은 자바 가 웹 매 직 을 오 르 는 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기