자바 로 간단하게 웹 매 직 을 오 르 는 법 을 알려 드릴 게 요.
1.1 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. Request
Request
URL 주소 에 대한 패키지 입 니 다.하나의 Request 는 URL 주소 에 대응 합 니 다.이것 은 PageProcessor 와 Downloader 가 상호작용 하 는 캐리어 이자 PageProcessor 가 Downloader 를 제어 하 는 유일한 방식 이다.
URL 자 체 를 제외 하고 키-Value 구조의 필드
extra
도 포함 되 어 있 습 니 다.extra 에 특수 한 속성 을 저장 한 다음 다른 곳 에서 읽 어서 다른 기능 을 수행 할 수 있 습 니 다.예 를 들 어 이전 페이지 의 일부 정 보 를 추가 하 는 등 이다.2. Page
Page
다운 로 더 에서 다운로드 한 페이지 인 HTML 일 수도 있 고 JSON 또는 다른 텍스트 형식의 내용 일 수도 있 습 니 다.페이지 는 웹 매 직 추출 과정의 핵심 대상 으로 추출,결과 저장 등 방법 을 제공 합 니 다.
3. ResultItems
ResultItems
는 하나의 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
대상,그리고 설정 키 는 각각:Page
과imgList
입 니 다.
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/
자바 로 간단하게 웹 매 직 을 오 르 는 방법 을 알려 드 리 는 이 글 은 여기까지 입 니 다.더 많은 자바 가 웹 매 직 을 오 르 는 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.