Phantomjs + Nodejs + Mysql 데이터 캡 처 (1. 데이터 캡 처)
26666 단어 PhantomJs
모든 페이지 의 내용 을 캡 처 합 니 다.
var page =require('webpage').create();
var address='http://product.pconline.com.cn/server/';
var fs = require('fs');
var mypath = 'version/server/server.txt';
var count = 2;
var pageSize=0;
phantom.outputEncoding="gbk";
page.settings.userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";
function loadController(status){
loadComputerList(address);
}
function loadComputerList(url){
console.log('loading '+url);
page.onLoadFinished = function loadListsucc(status){
console.log("loadlistSucc ["+url+"] =======================Status:"+status);
};
page.open(url,function(status){
setTimeout(function(){
console.log(status);
var content='';
content = page.evaluate(function(){
var cont='';
var listComputer = document.querySelectorAll('div.item-title>h3>a');
var listPrice =document.querySelectorAll('div.price');
for(var j=0;jvar computer = listComputer[j].innerText;
var price = listPrice[j].innerText;
var url = listComputer[j];
cont += computer+'\t\t :'+price+','+url+'\r
';
}
return cont;
});
console.log(content);
console.log('========== write to file !============');
try{
fs.write(mypath, content, 'a');
}catch(e){
console.log(e);
}
console.log('========== begin loading next page!============');
var nextUrl = page.evaluate(function(){
var url = '';
var next = document.querySelectorAll('div.pager a[class=page-next]');
var cont = '';
url = next[0];
cont += url;
return cont;
});
console.log(nextUrl);
if(count <= pageSize){
console.log(nextUrl);
count++;
console.log(count);
loadComputerList(nextUrl);
}else{
console.log(count);
phantom.exit();
}
}, 100);
});
}
page.open(address,function(status){
// page.onLoadFinished = loadController;
page.render('computer.jpeg');
pageSize = page.evaluate(function(){
var cont='';
var size =document.querySelector('div.pager>em>i').innerText;
cont += size;
return cont;
});
console.log(pageSize);
loadController(status);
});
위 코드 는 바로 잡 을 수 있 습 니 다.
http://product.pconline.com.cn/server/
이 페이지 의 모든 페이지 정보
다음은 코드 분석 을 진행 합 니 다.
page.open(address,function(status){
// page.onLoadFinished = loadController;
page.render('computer.jpeg');
pageSize = page.evaluate(function(){
var cont='';
var size =document.querySelector('div.pager>em>i').innerText;
cont += size;
return cont;
});
console.log(pageSize);
loadController(status);
});
이 부분 코드 는 Phantomjs 의 입구 이자 우리 가 데이터 캡 처 를 하 는 시작 부분 입 니 다.
var size =document.querySelector('div.pager>em>i').innerText;
여기 서 잡 은 정 보 는 모든 페이지 의 페이지 수 로 순환 판단 의 횟수 근거 로 사용 된다.
그리고 코드 를 관찰 하면 입구 가 끝 난 후에 LoadContriller 함수 로 넘 어간 다음 에 loadComputer List 라 는 함 수 를 호출 한 다음 에 데이터 캡 처 를 할 수 있 습 니 다.
다시 한 번 볼 게 요.
var listComputer = document.querySelectorAll('div.item-title>h3>a');
var listPrice =document.querySelectorAll('div.price');
이 두 단락 의 코드 는 바로 우리 가 캡 처 해 야 할 컴퓨터 URL 과 가격 의 정보 이다.우리 가 원 하 는 정 보 를 잡 은 후에 우 리 는 그것 을 맞 추 었 다.
for(var j=0;j<listComputer.length;j++){
var computer = listComputer[j].innerText;
var price = listPrice[j].innerText;
var url = listComputer[j];
cont += computer+'\t\t :'+price+','+url+'\r
';
}
그리고 기본 정 보 를 가 진 컴퓨터 속성 을 얻 습 니 다.그 다음 에 다음 작업 은 바로 이 정 보 를 저장 하 는 것 입 니 다. 우 리 는 데이터 베 이 스 를 직접 저장 할 수 없 기 때문에 먼저 텍스트 에 저장 해 야 합 니 다. 코드 는 다음 과 같 습 니 다.
var fs = require('fs');
try{
fs.write(mypath, content, 'a');
}catch(e){
console.log(e);
}
또한 PhantomJS 에 API 종류 가 있 는데 해당 하 는 읽 기와 쓰기 파일 설명 이 있 습 니 다. 여기 서 더 이상 말 하지 않 겠 습 니 다. 상기 코드 는 요청 을 받 은 후에 저희 가 맞 춘 내용 을 파일 에 기록 하 는 것 입 니 다. 사용 하 는 방식 은 'a' 가 추가 라 는 뜻 입 니 다.
상기 과정 을 통 해 우 리 는 첫 번 째 페이지 의 모든 기본 정 보 를 잡 을 수 있 습 니 다. 다음 문 제 는 우리 가 어떻게 다음 페이지 로 넘 어가 다음 내용 을 잡 아야 하 는 지 하 는 것 입 니 다.
코드 는 다음 과 같 습 니 다:
var nextUrl = page.evaluate(function(){
var url = '';
var next = document.querySelectorAll('div.pager a[class=page-next]');
var cont = '';
url = next[0];
cont += url;
return cont;
});
console.log(nextUrl);
if(count <= pageSize){
console.log(nextUrl);
count++;
console.log(count);
loadComputerList(nextUrl);
}else{
console.log(count);
phantom.exit();
}
다음 페이지 Url 을 가 져 오 는 데 사용 할 js 문 구 는 다음 과 같 습 니 다.
var next = document.querySelectorAll('div.pager a[class=page-next]');
여러분 은 개발 자 도 구 를 사용 하여 이 사이트 에 가서 다음 페이지 단 추 를 누 르 면 대응 하 는 dom 노드 가 무엇 인지 보고 이 코드 의 의 미 를 알 수 있 습 니 다.
그리고 이 안에서 우 리 는 다음 페이지 의 단 추 를 얻 은 후에 현재 의 순환 횟수 를 판단 해 야 한다. 다음 페이지 의 단 추 는 계속 존재 하기 때문에 우 리 는 빈 것 인지 아 닌 지 를 판단 해서 임 무 를 끝 낼 수 없 기 때문에 나 는 비교적 어 리 석 은 방법 으로 이 문 제 를 해결 했다.
모든 페이지 의 내용 을 캡 처 하면 기본적으로 완 성 됩 니 다. 이 스 크 립 트 코드 는 비교적 간단 합 니 다. 같은 사 이 트 를 잡 으 려 면 두 부분 만 수정 하면 됩 니 다. 하 나 는 address 라 는 입구 이 고 파일 을 쓰 는 경로 입 니 다.
자세 한 정보 캡 처
그리고 위 에서 우 리 는 이미 기본 적 인 정 보 를 잡 았 지만 페이지 에서 컴퓨터 cpu, 메모리, 그래 픽 카드 등 내용 을 제공 하지 않 았 기 때문에 우리 의 캡 처 작업 은 완성 되 지 않 았 다.그러면 다음 작업 은 우리 가 방금 잡 은 url 을 통 해 컴퓨터 상품 의 상세 한 정보 페이지 에 들 어간 다음 에 우리 가 필요 로 하 는 상세 한 정 보 를 잡 는 것 이다.코드 는 다음 과 같 습 니 다:
var page =require('webpage').create();
var address='http://product.pconline.com.cn/server/';
var fs = require('fs');
var mypath='version/Server/server_page.txt';
var stream = null;
var steams = null;
var K=1;
var line ='';
var cate ='';
var url = '';
var dragPath='version/Server/server_detail.txt';
phantom.outputEncoding="gbk";
page.settings.userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";
function start(url){
console.log(url);
page.open(url,function(status){
setTimeout(function(){
if(status == 'success'){
console.log('open success!');
console.log('==========begin work!=============');
stream = page.evaluate(function(){
var name = document.querySelector('.pro-tit>h1').innerText;
name = name.replace(' ','');
var listComputer = document.querySelectorAll('div.pannel>ul .title');
var listParameter = document.querySelectorAll('[itemid]');
var price = document.querySelector('.r-price').innerText;
price = price.replace(/
/g,'');
var cont= name+'|&|'+price+'|&| :';
for(var j=0;jvar computer = listComputer[j].innerText;
computer = computer.replace(' ','');
cont += computer+' ';
}
for( var j = 0;jvar parameter = listParameter[j].innerText;
parameter = parameter.replace(/
/g,'');
parameter = parameter.replace('\t',' ');
if(j1){
cont += parameter+"|&|";
}else{
cont += parameter+'';
}
}
return cont+'\r
';
});
try{
fs.write(dragPath, stream, 'a');
}catch(e){
console.log(e);
}
console.log(stream);
}else{
console.log('page open fail!');
}
before();
}, 100);
});
}
function readFile(status){
streams = fs.open(mypath,'r');
before();
}
function before(){
console.log('=========work in befor==========='+K);
K++;
if(!streams.atEnd()){
console.log('=========work in befor get Next Line===========');
line = streams.readLine();
cate = line.split(',');
console.log(cate[1]);
var pcUrl = cate[1].replace('.html','_detail.html');
console.log(pcUrl);
start(pcUrl);
}else{
console.log('end!!!!!!!!!!!!');
phantom.exit();
}
}
page.open(address,function(status){
readFile(status);
})
우 리 는 코드 를 계속 분석 해 보 았 습 니 다. Phantomjs 의 시작 입 구 는 말 하지 않 겠 습 니 다. 매번 phantomjs 를 시작 할 때마다 이 입구 에서 시작 한 다음 에 우리 가 원 하 는 작업 으로 갑 니 다.
function readFile(status){
streams = fs.open(mypath,'r');
before();
}
파일 을 성공 적 으로 열 었 고 파일 의 내용 을 streams 에 캐 시 했 습 니 다. 전역 변 수 를 설정 하 였 기 때문에 before 함수 로 바로 뛰 어 들 었 습 니 다.
function before(){
console.log('=========work in befor==========='+K);
K++;
if(!streams.atEnd()){
console.log('=========work in befor get Next Line===========');
line = streams.readLine();
cate = line.split(',');
console.log(cate[1]);
var pcUrl = cate[1].replace('.html','_detail.html');
console.log(pcUrl);
start(pcUrl);
}else{
console.log('end!!!!!!!!!!!!');
phantom.exit();
}
}
이 안에서 진행 되 는 조작 은 주로 파일 을 잡기 전에 우 리 는 우리 가 방금 읽 은 내용 을 분석 해 야 한다. 예 를 들 어:
line = streams.readLine();
cate = line.split(',');
var pcUrl = cate[1].replace('.html','_detail.html');
이 세 부분 은 먼저 한 줄 한 줄 읽 기 기능 을 실현 하고 모든 줄 의 내용 을 읽 은 다음 에 구분자 로 Url 을 얻 는 것 입 니 다. 여기 서 우리 가 얻 은 url 은 우리 가 원 하 는 상세 한 정보 url 이 아니 기 때문에 우 리 는 조합 을 해 야 합 니 다.
http://product.pconline.com.cn/server/lenovo/514943.html
http://product.pconline.com.cn/server/lenovo/514943_detail.html
여기 서 두 단락 의 실례 를 제공 하 니 독자 들 은 들 어가 서 한 번 보면 우리 가 왜 이렇게 URL 을 연결 해 야 하 는 지 알 수 있다
stream = page.evaluate(function(){
var name = document.querySelector('.pro-tit>h1').innerText;
name = name.replace(' ','');
var listComputer = document.querySelectorAll('div.pannel>ul .title');
var listParameter = document.querySelectorAll('[itemid]');
var price = document.querySelector('.r-price').innerText;
price = price.replace(/
/g,'');
var cont= name+'|&|'+price+'|&| :';
for(var j=0;jvar computer = listComputer[j].innerText;
computer = computer.replace(' ','');
cont += computer+' ';
}
for( var j = 0;jvar parameter = listParameter[j].innerText;
parameter = parameter.replace(/
/g,'');
parameter = parameter.replace('\t',' ');
if(j1){
cont += parameter+"|&|";
}else{
cont += parameter+'';
}
}
return cont+'\r
';
});
이 부분의 코드 는 바로 우리 가 상세 한 정 보 를 얻 으 려 는 코드 이다. 독 자 는 연구 할 수 있다. 사실은 원 리 는 노드 를 찾 은 다음 에 꺼 내 서 연결 하 는 것 이다. 마지막 으로 상세 한 정보, 사례 를 얻 는 것 이다.
ThinkServer TS130 S1225/2G/500O|&|¥5417|&| : TS130 S1225/2G/500O|&| |&| 4U|&|CPU E3 ,Intel|&|CPU |&| DMI 5GT/s|&|CPU E3-1225|&|CPU 3.1GHz|&| 6M|&| CPU 1 |&| 1×PCIE 2.0 x161×PCIE 2.0 x12×PCI 32/33|&| DDR3|&| 2G|&| 32G|&| SATAⅢ|&| 500G|&| 4TB|&| 7200 |&| Raid 0,Raid 1|&| DVD-ROM |&| |&| |&| :10℃-35℃, :10%-80%|&| :-40℃-70℃, :10%-90%|&| 1 80PLUS |&| 280W|&| Windows 2003 R2 SP2 (32 /64 ) Windows 2003 R2 SP2 (32 /64 )Windows Server 2008 (64 ) Windows Server 2008 (32 /64 )Windows Server 2008 (32 /64 )Windows Server 2008 R2 (64 )Windows Server 2008 R2 (64 ) Windows Server 2008 R2 (64 ) Windows Small Business Server 2011 Essential Windows XP ,SP2Windows Vista Business Windows 7 (32 /64 )Windows 7 (32 /64 )|&| 406×377×174mm
위의 이 부분 은 우리 가 얻 은 상세 한 컴퓨터 정보 내용 이다. 그리고 정 보 를 맞 춘 후에 우리 가 해 야 할 일 은 바로 파일 에 쓰 는 것 이다. 여 기 는 위 와 비슷 해서 나 는 반복 하지 않 을 것 이다.