www.qjdy.com-奇迹赌场 > 佳美特设计 > 其实写爬虫的思路十分简单

原标题:其实写爬虫的思路十分简单

浏览次数:189 时间:2019-07-12

其实写爬虫的思路特别大约:

  • 根据一定的法规发送 HTTP 央求获得页面 HTML 源码(须求时索要增多一定的 HTTP 头消息,譬如 cookie 或 referer 之类)
  • 应用正则相称或第三方模块解析 HTML 代码,提取有效数据
  • 将数据持久化到数据库中

只是真的写起那一个爬虫来,笔者要么蒙受了十分的多的主题素材(和自身的功底不踏实也许有不小的涉嫌,node.js 并不曾怎么认真的学过)。重要依然 node.js 的异步和回调知识未有完全通晓,导致在写代码的历程中走了无数弯路。

模块化

模块化对于 node.js 程序是至关心注重要的,不能够像原本写 PHP 那样具备的代码都扔到八个文本里(当然那只是本身个人的陋习),所以一发轫就要深入分析这些爬虫须求贯彻的机能,并大约的分割了五个模块。

主程序,调用爬虫模块和长久化模块完成完整的爬虫作用
爬虫模块,依照传来的数额发送央浼,深入分析 HTML 并领取有用多少,重返四个指标
悠久化模块,接受四个目标,将个中的开始和结果积攒到数据库中
模块化也带动了麻烦了自家一个早晨的题目:模块之间的异步调用导致数据失实。其实自身迄今都不太知道难题到底出在何方,鉴于脚本语言不那么平价的调解功效,一时还并没有深切探讨。

别的一些急需留意的是,模块化时尽量慎用全局对象来囤积数据,因为可能您这么些模块的二个作用还尚未终止,这几个全局变量已经被改换了。

Control Flow

以此事物很难翻译,直译叫调控流(吗)。颇负盛名,node.js 的核心情想就是异步,可是异步多了就能时有爆发有些层嵌套,代码实在难看。那年,你需求依附一些 Control Flow 模块来重新整理你的逻辑。在那边将要推荐开采社区那些生动活泼,用起来也很顺手的 async.js(

async 提供了众多实用的方法,我在写爬虫时首要行使了

  • async.eachSeries(arr, fn, callback)  依次把 arr 中的每叁个元素传给 fn,若 fn 回调未有回来错误对象就卫冕传下三个,不然把错误对象传给 callback,循环截至
  • async.parallel(fn[, fn] , callback)  当有着的 fn 都奉行到位后施行callback

这几个调整流方法给爬虫的支出职业推动了非常的大的惠及。牵挂那样贰个选拔场景,你需求把多少条数据插入数据库(属于同二个学员),你须要在具有数据都插入完结后本领回到结果,那么怎么着保管具有的插入操作都终止了呢?只可以是难得回调保险,假设用 async.parallel 就有利于多了。

此处再多提一句,本来保证具有的插入都实现这么些操作能够在 SQL 层完毕,即 transaction,然而 node-mysql 结束笔者利用的时候依旧不曾很好的扶助transaction,所以只有团结手动用代码保险了。

解析 HTML

在分析进程中也越过有个别主题材料,这里一并记录下来。

最大旨的出殡 HTTP 央求获得 HTML 代码,使用 node 自带的 http.request 作用就可以。假诺是爬简单的从头到尾的经过,比方获得某些钦定 id 成分中的内容(常见于抓去商品价位),那么正则足以实现职务。不过对于复杂的页面,特别是多少项非常多的页面,使用 DOM 会尤其有益于高效。

而 node.js 最好的 DOM 实现非 cheerio( 莫属了。其实 cheerio 应该算是 jQuery 的八个对准 DOM 操作优化和轻巧的子集,满含了 DOM 操作的大比非常多情节,去除了其它不须要的内容。使用 cheerio 你就能够像用一般 jQuery 选取器那样选用你须求的剧情。

下载图片 在爬数据时,我们也许还亟需下载图片。其实下载图片的方法和平凡的网页没有太大的不相同,不过有某个让自己吃了横祸。

留心上边代码中言辞激烈的注明,这就是本身年轻时犯下的百无一用……

var req = http.request(options, function(res){

  //初始化数据!!!
  var binImage = '';

  res.setEncoding('binary');
  res.on('data', function(chunk){
   binImage  = chunk;
  });

  res.on('end', function(){

   if (!binImage) {
    console.log('image data is null');
    return null;
   }

   fs.writeFile(imageFolder   filename, binImage, 'binary', function(err){
    if (err) {
     console.log('image writing error:'   err.message);
     return null;
    }
    else{
     console.log('image '   filename   ' saved');
     return filename;
    }
   });
  });

  res.on('error', function(e){
   console.log('image downloading response error:'   e.message);
   return null;
  });
 });

 req.end();

GBK 转码 另外八个值得一说明的标题便是 node.js 爬虫在爬 GBK 编码内容时转码的难点,其实那几个难题很好化解,然则菜鸟可能会绕弯路。这里就把源码全体奉上:

var req = http.request(options, function(res) {
  res.setEncoding('binary');
  res.on('data', function (chunk) {
  html  = chunk;
  });

  res.on('end', function(){
  //转换编码
  html = iconv.decode(html, 'gbk');
  });
 });

 req.end();

此地本人使用的转码库是 iconv-lite( GBK 和 GB2312 等双字节编码。

实例:爬虫批量下载百度图表

var fs = require('fs'), 
 path = require('path'), 
 util = require('util'), // 以上为Nodejs自带依赖包 
 request = require('request'); // 需要npm install的包 

// main函数,使用 node main执行即可 
patchPreImg(); 

// 批量处理图片 
function patchPreImg() { 
 var tag1 = '摄影', tag2 = '国家地理', 
  url = 'http://image.baidu.com/data/imgs?pn=%s&rn=60&p=channel&from=1&col=%s&tag=%s&sort=1&tag3=', 
  url = util.format(url, 0, tag1, tag2), 
  url = encodeURI(url), 
  dir = 'D:/downloads/images/', 
  dir = path.join(dir, tag1, tag2), 
  dir = mkdirSync(dir); 

 request(url, function(error, response, html) { 
  var data = JSON.parse(html); 
  if (data && Array.isArray(data.imgs)) { 
   var imgs = data.imgs; 
   imgs.forEach(function(img) { 
    if (Object.getOwnPropertyNames(img).length > 0) { 
     var desc = img.desc || ((img.owner && img.owner.userName)   img.column); 
     desc  = '('   img.id   ')'; 
     var downloadUrl = img.downloadUrl || img.objUrl; 
     downloadImg(downloadUrl, dir, desc); 
    } 
   }); 
  } 
 }); 
} 

// 循环创建目录 
function mkdirSync(dir) { 
 var parts = dir.split(path.sep); 
 for (var i = 1; i <= parts.length; i  ) { 
  dir = path.join.apply(null, parts.slice(0, i)); 
  fs.existsSync(dir) || fs.mkdirSync(dir); 
 } 
 return dir; 
} 

var index = 1; 
// 开始下载图片,并log统计日志 
function downloadImg(url, dir, desc) { 
 var fileType = 'jpg'; 
 if (url.match(/.(w )$/)) fileType = RegExp.$1; 
 desc  = '.'   fileType; 
 var options = { 
  url: url, 
  headers: { 
   Host: 'f.hiphotos.baidu.com', 
   Cookie: 'BAIDUID=810ACF57B5C38556045DFFA02C61A9F8:FG=1;' 
  } 
 }; 
 var startTime = new Date().getTime(); 
 request(options) 
  .on('response', function() { 
   var endTime = new Date().getTime(); 
   console.log('Downloading...%s.. %s, 耗时: %ss', index  , desc, (endTime - startTime) / 1000); 
  }) 
  .pipe(fs.createWriteStream(path.join(dir, desc))); 
} 

您大概感兴趣的稿子:

  • 行使NodeJS和PhantomJS抓取网址页面音讯以及网址截图
  • 用Node.js通过sitemap.xml批量抓取美人图片
  • nodejs制作爬虫完成批量下载图片
  • 行使node.js写二个爬取知乎妹纸图的小爬虫
  • nodejs实现爬取网址图片功效
  • Node Puppeteer图像识别完成百度指数爬虫的亲自去做
  • ajax node request爬取网络图片的实例(土冒福利)
  • 动用Node.js批量抓取高清妹子图片实例教程

本文由www.qjdy.com-奇迹赌场发布于佳美特设计,转载请注明出处:其实写爬虫的思路十分简单

关键词: PG电子游艺

上一篇:返回去重后的新数组

下一篇:没有了