Phantomjs+Nodejs+Mysql数据抓取(2.抓取图片)
概要
这篇博客是在上一篇博客Phantomjs+Nodejs+Mysql数据抓取(1.抓取数据)
后进行的第二部分,请各位读者在看这篇博客之前先浏览上一篇,因为这里面有部分代码会沿用到上一部分的抓取结果。
好,现在开始正式的抓取图片的讲解
首先,我们先来看看代码:
var page =require('webpage').create(); var address='http://product.pconline.com.cn/notebook/series/417764.html'; var fs = require('fs'); var mypath='version/Server/server.txt'; var stream = null; var steams = null; var files = null; var K=1; var line =''; var cate =''; var url = ''; var dragPath='version/Server/server_img.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){ page.open(url,function(status){ setTimeout(function(){ if(status == 'success'){ console.log('open success!'); console.log('==========begin work!============='); stream = page.evaluate(function(){ var title = document.querySelector('.pro-info').innerText; // title = title.replace('图片',''); var cont = document.querySelectorAll('.pics>li>a>img')[1].src; // var imgUrls = document.querySelectorAll('.pics>li>a>img')[0].src; var href = document.querySelector('.pics>li>a'); return title+':'+cont+':'+href+'\r\n'; }); console.log(stream); try{ fs.write(dragPath, stream, 'a'); }catch(e){ console.log(e); fs.write(dragPath, null, 'a'); } }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(','); var imgUrl = cate[1].replace('http://product.pconline.com.cn/server/',''); var imgs = imgUrl.split('/'); var imgsUrl = imgs[1].split('.'); imgsUrl = 'http://product.pconline.com.cn/pdlib/'+imgsUrl[0]+'_picture.html'; console.log(imgsUrl); start(imgsUrl); }else{ console.log('end!!!!!!!!!!!!'); phantom.exit(); } } page.open(address,function(status){ readFile(status); })
这部分代码的结构和前面的都很相似,下面我们继续进行代码剖析
page.open(address,function(status){ readFile(status); })
与前面相似,这里是我们代码的入口,程序启动的入口。
然后会调用readFile函数
function readFile(status){ streams = fs.open(mypath,'r'); before(); }
这里使用phantomjs里面的fs请求,主要就是用来解决文件读取的问题
var fs = require('fs');
再读取到文件之后,我们将进行数据处理:
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(','); var imgUrl = cate[1].replace('http://product.pconline.com.cn/server/',''); var imgs = imgUrl.split('/'); var imgsUrl = imgs[1].split('.'); imgsUrl = 'http://product.pconline.com.cn/pdlib/'+imgsUrl[0]+'_picture.html'; console.log(imgsUrl); start(imgsUrl); }else{ console.log('end!!!!!!!!!!!!'); phantom.exit(); } }
我们可以先来看看原本数据是什么样的:
联想ThinkServer TS130 S1225/2G/500O 价格:¥5417,http://product.pconline.com.cn/server/lenovo/514943.html
上面是我们从文件中读取到的数据,这一段数据都属于这个品牌电脑的数据。在读取完之后,我们对url进行拼接。
http://product.pconline.com.cn/pdlib/514943_picture.html
这个是我们要获取到的目的url,读者可以自己研究有什么规律,我这里的拼接方法有点挫。你们可以自己改进。
function start(url){ page.open(url,function(status){ setTimeout(function(){ if(status == 'success'){ console.log('open success!'); console.log('==========begin work!============='); stream = page.evaluate(function(){ var title = document.querySelector('.pro-info').innerText; // title = title.replace('图片',''); var cont = document.querySelectorAll('.pics>li>a>img')[1].src; // var imgUrls = document.querySelectorAll('.pics>li>a>img')[0].src; var href = document.querySelector('.pics>li>a'); return title+':'+cont+':'+href+'\r\n'; }); console.log(stream); try{ fs.write(dragPath, stream, 'a'); }catch(e){ console.log(e); fs.write(dragPath, null, 'a'); } }else{ console.log('page open fail!'); } before(); }, 100); }); }
最后调用数据抓取的函数,
var title = document.querySelector('.pro-info').innerText; // title = title.replace('图片',''); var cont = document.querySelectorAll('.pics>li>a>img')[1].src; // var imgUrls = document.querySelectorAll('.pics>li>a>img')[0].src; var href = document.querySelector('.pics>li>a'); return title+':'+cont+':'+href+'\r\n';
这里面的就是我们要抓数据的处理,分别获取到的是标题,小图的绝对地址,已经大图的url。
联想ThinkServer TS130 S1225/2G/500O图片:http://img.pconline.com.cn/images/product/5149/514938/TS130-b_sn8.jpg:http://product.pconline.com.cn/pdlib/514943_bigpicture7748163.html
这部分数据就是其中一条我们抓取到的数据。再抓完之后会进行写入操作,然后再重新调用before()方法,进行循环调用,直至读取玩文件的所有内容。
以上就是我们进行图片抓取的全部过程,原本还有一份代码是用来抓取大图的,但是由于与本文的内容相似度极高,所以这里我就不列出来了。读者可以参考这篇文章进行大图的抓取。
NodeJs 图片下载
接下来我在讲一下如何对我们刚刚抓下来的图片绝对地址进行文件下载。
先上代码:
var request = require('request'); var lineReader = require('line-reader'); var fs = require('fs'); var i=0; lineReader.eachLine('imgs.txt', {encoding: 'utf8'},function(line, last) { var cate = line.split(':'); var url1 = cate[1]; var tt = cate[0].replace(/\//g,','); i++; console.log(tt+'==============>'+i); if(!(url1 == 'null')){ tt = tt.replace(/\s/g,''); tt = tt.replace(/[^a-z\d]/ig,""); var filename1 = 'images/router_large/'+tt+'bPic.jpg' request(url1).pipe(fs.createWriteStream(filename1)); } });
没错代码就那么短,我们来一段一段的分析:
lineReader.eachLine('imgs.txt', {encoding: 'utf8'},function(line, last)
这里是我们下载文件的入口,使用到了nodejs里面的
var lineReader = require('line-reader');
这段代码的用处就是逐行读取文件。
tt = tt.replace(/\s/g,'');
tt = tt.replace(/[^a-z\d]/ig,"");
这里面我主要是处理一下文件名,除去了一些特殊符号已经中文名,便于存入数据库。
request(url1).pipe(fs.createWriteStream(filename1));
最后调用这部分代码进行文件下载。
以上就是抓取图片的全部内容,谢谢观看。