Phantomjs+Nodejs+Mysql数据抓取(1.数据抓取)
概要:
这篇博文主要讲一下如何使用Phantomjs进行数据抓取,这里面抓的网站是太平洋电脑网估价的内容。主要是对电脑笔记本以及他们的属性进行抓取,然后在使用nodejs进行下载图片和插入数据库操作。
先进行所有页面的内容进行抓取
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\n';
}
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 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函数中去,然后再调用loadComputerList这个函数,然后就可以进行数据抓取了
我们再看一下
var listComputer = document.querySelectorAll('div.item-title>h3>a');
var listPrice =document.querySelectorAll('div.price');
这两段代码,就是我们要抓取的电脑URL以及价格的信息。
再抓到我们想要的信息之后,我们再对其进行拼接
for(var j=0;jlistComputer.length;j++){
var computer = listComputer[j].innerText;
var price = listPrice[j].innerText;
var url = listComputer[j];
cont += computer+'\t\t价格:'+price+','+url+'\r\n';
}
然后获得一行具有基本信息的电脑属性。
然后接下来的工作就是要把这些信息进行存储,我们这里因为不能直接存入数据库,所以要先存入文本中,代码如下:
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 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(/\n/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(/\n/g,'');
parameter = parameter.replace('\t',' ');
if(j1){
cont += parameter+"|&|";
}else{
cont += parameter+'';
}
}
return cont+'\r\n';
});
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(/\n/g,'');
var cont= name+'|&|'+price+'|&|产品特性:';
for(var j=0;jvar computer = listComputer[j].innerText;
computer = computer.replace(' ','');
这部分代码就是我们要获取详细信息的代码了,读者可以研究一下,其实原理就是找到节点,然后取出来,进行拼接,最后获得一个详细的信息,实例:
联想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
上面这部分就是我们获取到的详细的电脑信息内容,然后再拼接完信息之后,我们要做的就是写入文件中去,这里和上面是相似的,我就不重复了。
Phantomjs+Nodejs+Mysql数据抓取(1.数据抓取)的更多相关文章
- Phantomjs+Nodejs+Mysql数据抓取(2.抓取图片)
概要 这篇博客是在上一篇博客Phantomjs+Nodejs+Mysql数据抓取(1.抓取数据) http://blog.csdn.net/jokerkon/article/details/50868 ...
- [原创.数据可视化系列之十二]使用 nodejs通过async await建立同步数据抓取
做数据分析和可视化工作,最重要的一点就是数据抓取工作,之前使用Java和python都做过简单的数据抓取,感觉用的很不顺手. 后来用nodejs发现非常不错,通过js就可以进行数据抓取工作,类似jqu ...
- [Python爬虫] 之八:Selenium +phantomjs抓取微博数据
基本思路:在登录状态下,打开首页,利用高级搜索框输入需要查询的条件,点击搜索链接进行搜索.如果数据有多页,每页数据是20条件,读取页数 然后循环页数,对每页数据进行抓取数据. 在实践过程中发现一个问题 ...
- 爬虫抓取页面数据原理(php爬虫框架有很多 )
爬虫抓取页面数据原理(php爬虫框架有很多 ) 一.总结 1.php爬虫框架有很多,包括很多傻瓜式的软件 2.照以前写过java爬虫的例子来看,真的非常简单,就是一个获取网页数据的类或者方法(这里的话 ...
- 使用NodeJS+AngularJS+MongoDB实现一个Web数据扒取-分析-展示的系统
说到Web爬虫,Python占了半壁江山.但是Web页面不是Python的强项了,如果需要扒取Web数据,再Mashup出来一个自己的系统,全端JS是个不错的解决方案(其实不用Python扒数据是因为 ...
- 使用selenium webdriver+beautifulsoup+跳转frame,实现模拟点击网页下一页按钮,抓取网页数据
记录一次快速实现的python爬虫,想要抓取中财网数据引擎的新三板板块下面所有股票的公司档案,网址为http://data.cfi.cn/data_ndkA0A1934A1935A1986A1995. ...
- 数据抓取的艺术(三):抓取Google数据之心得
本来是想把这部分内容放到前一篇<数据抓取的艺术(二):数据抓取程序优化>之中.但是随着任务的完成,我越来越感觉到其中深深的趣味,现总结如下: (1)时间 时间是一个与抓取规模相形而 ...
- Charles 如何抓取https数据包
Charles可以正常抓取http数据包,但是如果没有经过进一步设置的话,无法正常抓取https的数据包,通常会出现乱码.举个例子,如果没有做更多设置,Charles抓取https://www.bai ...
- 手把手教你用python打造网易公开课视频下载软件3-对抓取的数据进行处理
上篇讲到抓取的数据保存到rawhtml变量中,然后通过编码最终保存到html变量当中,那么html变量还会有什么问题吗?当然会有了,例如可能html变量中的保存的抓取的页面源代码可能有些标签没有关闭标 ...
随机推荐
- 谈谈DOMContentLoaded:Javascript中的domReady引入机制
一.扯淡部分 回想当年,在摆脱写页面时js全靠从各种DEMO中copy出来然后东拼西凑的幽暗岁月之后,毅然决然地打算放弃这种处处“拿来主义”的不正之风,然后开启通往高大上的“前端攻城狮”的飞升之旅.想 ...
- 标准产品+定制开发:专注打造企业OA、智慧政务云平台——山东森普软件,交付率最高的技术型软件公司
一.公司简介山东森普信息技术有限公司(以下简称森普软件)是一家专门致力于移动互联网产品.企业管理软件定制开发的技术型企业.公司总部设在全国五大软件园之一的济南齐鲁软件园.森普SimPro是由Simpl ...
- 【Win 10 应用开发】启动远程设备上的应用
这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...
- Mysql事务探索及其在Django中的实践(一)
前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...
- Entity Framework 手动使用migration里面的up 和down方法。
add-migration -IgnoreChanges 201606100717405_201606100645298_InitialCreate 执行这一句后 ,清空使用map生成的代码,个人不太 ...
- MySQL 系列(三)你不知道的 视图、触发器、存储过程、函数、事务、索引、语句
第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...
- [原] KVM 虚拟化原理探究(3)— CPU 虚拟化
KVM 虚拟化原理探究(3)- CPU 虚拟化 标签(空格分隔): KVM [TOC] CPU 虚拟化简介 上一篇文章笼统的介绍了一个虚拟机的诞生过程,从demo中也可以看到,运行一个虚拟机再也不需要 ...
- 如何优化coding
如何优化coding 前言 最近一直在做修改bug工作,修改bug花费时间最多的不是如何解决问题而是怎样快速读懂代码.如果代码写的好的,不用debug就可以一眼看出来哪里出了问题.实际上,我都要deb ...
- STM32F429 LCD程序移植
STM32F429自带LCD驱动器,这一具有功能给我等纠结于屏幕驱动的程序员带来了很大的福音.有经验的读者一定有过这样的经历,用FSMC驱动带由控制器的屏幕时候,一旦驱动芯片更换,则需要重新针对此驱动 ...
- 2Sum
用哈希表(unordered_map)使得时间复杂度从O(n*n)降到O(n),空间复杂度从O(1)增到O(n):一边找一边插入哈希表 注意 在C++11以前要使用unordered_map需要 #i ...