HTML해석 - 링크와 이미지 추출
스크래핑이란?
스크래핑이란 웹사이트에서 HTML 데이터를 수집하고, 특정 데이터를 추출, 가공하여 저정하는 것을 말한다.
단순히 웹사이트에서 HTML 파일을 다운로드하는 것이 아니라, HTML 파일의 각 요소들을 분석하는 과정을 포함한다.
cheerio-httpcli 모듈 설치
$ npm install cheerio-httpcli
NodeJs를 활용하여 스크래핑 할때 편리한 모듈이 cheerio-httpcli이다.
이 모듈을 사용하면 파일을 쉽게 다운로드 받고 JQuery와 비슷하게 요소를 획득할 수 있다.
웹 페이지의 문자 코드도 자동으로 판정하여 읽어준다. 페이지 안의 데이터를 꺼낼 때 간편하게 지정한 요소를 추출할 수 있어, 페이지 안의 링크나 이미지를 쉽게 추출할 수있다.
HTML 문서 다운 & 출력 (cheerio-httpcli 모듈)
// 0202_getpage.js
// 모듈 로드
var client = require('cheerio-httpcli');
// 다운로드
var url = "http://jpub.tistory.com";
var param = {};
// fetch(URL, 파라미터, 콜백함수) ->콜백함수는 웹사이트에서 데이터 취득이 완료된 시점에 실행된다.
client.fetch(url, param, function(err, $, res){
// 에러체크
if(err){
console.log("Error:",err);
return;
}
//다운로드 한 결과를 화면에 출력
var body = $.html();
console.log(body);
});
$node getpage.js
결과 화면
HTML 파일에서 링크 추출
// 0202_showlink.js
// 모듈 로드
var client = require('cheerio-httpcli');
// 다운로드
var url = "http://jpub.tistory.com";
var param = {};
client.fetch(url, param, function(err, $, res){
// 에러체크
if(err){ console.log("Error:",err); return;}
//링크를 추출하여 표시
//$("a") -> HTML 내 모든 <a> 태그를 추출한다.
// each() 메소드를 통해 추출한 각 요소들에 대해 지정한 함수를 수행할 수 있다.
$("a").each(function(idx){
var text = $(this).text();
var href = $(this).attr('href');
console.log(text + ":" + href);
});
});
$ node 0202_showlink.js
결과 화면
상대 URL을 절대 URL로 변경 (url모듈 resolve 메소드)
node.js의 url이라는 표준 모듈을 사용하면 상대 경로를 절대 경로로 바꿀 수 있다.
url 모듈의 resolve 메소드를 사용하는데, 기본 URL과 상대 URL을 인자로 주면 절대 경로가 반환된다.
//0202_showlink-path.js
// 모듈 로드
var client = require('cheerio-httpcli');
var urlType = require('url'); // 절대경로 생성을 위해 url 모듈 로드
// 다운로드
var url = "http://jpub.tistory.com";
var param = {};
client.fetch(url, param, function(err, $, res){
// 에러체크
if(err){ console.log("Error:",err); return;}
//링크를 추출하여 표시
$("a").each(function(idx){
var text = $(this).text();
var href = $(this).attr('href');
if(!href) return;
//상대 경로를 절대 경로로 변환
var href2 = urlType.resolve(url, href);
console.log(text + ":" + href);
console.log(" => " + href2 + "\n");
});
});
이미지 파일 추출
페이지에 삽입된 이미지 파일 추출
- <img> 태그를 추출하여
- src 속성에 지정된 이미지 파일의 경로 추출
// 0202_showimage.js
// 모듈 로드
var client = require('cheerio-httpcli');
var urlType = require('url');
// 다운로드
var url = "https://ko.wikipedia.org/wiki/" + encodeURIComponent("강아지");
var param = {};
client.fetch(url, param, function(err, $, res){
if(err){ console.log("Error:",err); return;}
//링크를 추출하여 표시
$("img").each(function(idx){
var src = $(this).attr('src');
src = urlType.resolve(url, src);
console.log(src);
});
});
이미지 다운로드 (request 모듈)
이미지를 다운로드 하는데는 request 모듈이 편리하다. 리다이렉트 지시가 있으면 자동으로 리다이렉트 된 곳에서 파일을 다운로드 해준다.
HTML에 연결된 이미지를 모두 다운로드하는 프로그램을 작성해본다.
//0202_06_dl-image.js
// 모듈 로드
var client = require('cheerio-httpcli');
var request = require('request');
var fs = require('fs');
var urlType = require('url');
// 저장할 디렉토리가 없으면 생성
var savedir = __dirname + "/img"; //
if(!fs.existsSync(savedir)){
fs.mkdirSync(savedir);
}
// URL 지정
var url = "https://ko.wikipedia.org/wiki/" + encodeURIComponent("강아지");
var param ={};
// HTML 파일 획득
client.fetch(url, param, function(err, $, res){
if(err) {console.log("err"); return;}
//img 링크 추출하여 각 링크에 대해 함수 수행
$("img").each(function(idx){
var src = $(this).attr('src');
//상대 경로를 절대 경로로 변환
src = urlType.resolve(url, src);
// 저장 파일 이름 결정
var fname = urlType.parse(src).pathname;
fname = savedir + "/" +fname.replace(/[^a-zA-Z0-9\.]+/g, '-');
//다운로드
request(src).pipe(fs.createWriteStream(fname));
});
});
var savepath = "test.html";
//다운로드
request(url).pipe(fs.createWriteStream(savepath));
fs.existsSync() 메소드는 파일이나 디렉토리의 존재 여부를 확인하고, fs.mkdirSync()로 디렉토리를 만든다
참고로 fs.exist()와 fs.mkdir() 메소드는 비동기적으로 동작한다. 파일이나 디렉토리의 작성이 완료된 시점에서 두번째 인자로 지정한 콜백함수가 호출된다.
면, fs.mkdirSync() 메소드는 디렉토리의 작성이 완료될 때까지 스크립트의 흐름을 멈추고 대기한다.