
目录
前言:
代理ip获取本文介绍了如何从零开始开发一个nodejs爬虫,以及如何使用node-crawler来实现一个爬虫。
1.Robots协议
存放于网站根目录的文件,定义了哪些目录可以抓取,哪些目录禁止抓取。
举个例子中国天气网
访问:域名+/robots.txt,http://www.weather.com.cn/robots.txt
User-agent: * Allow: /可以看到,任意用户代理,允许爬取所有
2.开始前准备两个库
superagent(客户端请求代理)cheerio(nodejs中的jquery)3.superagent库的使用
安装npm install superagent 使用const superagent = require(superagent); //客户端代理,用来发送get、post等请求 let BASE_URL = "";//要爬取的地址 superagent.get(BASE_URL) .end((err, res) => { if (err) { return console.error(err); } console.log(res) //这里是爬到的内容 }); //输出: { statusCode: 200, status: 200, statusType: 2, info: false, ok: true, redirect: false, clientError: false, serverError: false, error: false, created: false, accepted: false, noContent: false, badRequest: false, unauthorized: false, notAcceptable: false, forbidden: false, notFound: false, unprocessableEntity: false, type: text/html, charset: utf-8, links: {}, setEncoding: [Function: bound ], redirects: [], pipe: [Function], [Symbol(kCapture)]: false, text:{ //内容为爬到的html,太多了,暂时略去,这块内容也是我们接下来要处理的 } }4.cheerio库
nodejs中的jquery,用来处理爬到的html,从中筛选我们需要的数据//从爬取到的代理ip获取数据中筛选出正在热映的影片信息 const superagent = require(superagent); const cheerio = require(cheerio); let BASE_URL = ""; superagent.get(BASE_URL) .end((err, res) => { if (err) { return console.error(err); } let $ = cheerio.load(res.text); //载入我们要处理的数据 let arr = [];//创建一个数组,用来存储我们处理完的数据 //这里我们通过分析爬取到的html,找到我们要 $(#nowplaying .lists .list-item).each((index, item) => { let title = $(item).find(.stitle .ticket-btn).attr(title); let score = $(item).find(.subject-rate).text().replace(/\n\s{1,}|\t/g, "");//正则去除回车换行等操作符 let imgUrl = $(item).find(img).attr(src); arr.push({ title,score,imgUrl }) }); console.log(arr) }); //输出: [ { title: 心灵奇旅, score: 9.1, imgUrl: }, { title: 拆弹专家2, score: 8.0, imgUrl: }, { title: 晴雅集, score: 5.1, imgUrl: }, { title: 神奇女侠1984, score: 6.5, imgUrl: }, { title: 明天你是否依然爱我, score: 4.1, imgUrl: }, { title: 紧急救援, score: 6.3, imgUrl: }, { title: 沐浴之王, score: 6.5, imgUrl: }, { title: 棒!少年, score: 8.7, imgUrl: }, { title: 疯狂原始人2, score: 8.1, imgUrl: }, { title: 赤狐书生, score: 5.1, imgUrl: }, { title: 如果声音不记得, score: 4.0, imgUrl: }, { title: 隐形人, score: 7.2, imgUrl: }, { title: 除暴, score: 6.5, imgUrl: }, { title: 猎杀T34, score: 7.5, imgUrl: }, { title: 哆啦A梦:大雄的新恐龙, score: 7.5, imgUrl: }, { title: 奇妙王国之魔法奇缘, score: , imgUrl: }, { title: 封口者, score: , imgUrl: }, { title: 我和我的家乡, score: 7.4, imgUrl: }, { title: 末日逃生, score: 5.6, imgUrl: }, { title: 金刚川, score: 6.5, imgUrl: }, { title: 真假美猴王之大圣无双, score: 4.1, imgUrl: }, { title: 宝可梦:超梦的逆袭 进化, score: 6.4, imgUrl: }, { title: 野性的呼唤, score: 7.2, imgUrl: }, { title: 汪汪队立大功之超能救援, score: 6.1, imgUrl: }, { title: 代理ip获取掬水月在手, score: 8.0, imgUrl: } ]5.更进一步,将图片保存至本地
//操作前,先在项目下新建个image目录,用来存放下载的图片 const superagent = require(superagent); const cheerio = require(cheerio); var fs = require(fs);//nodejs核心模块,用来处理数据流 let BASE_URL = ""; superagent.get(BASE_URL) .end((err, res) => { if (err) { return console.error(err); } let $ = cheerio.load(res.text); let arr = []; //选取所需节点,并循环 $(#nowplaying .lists .list-item).each((index, item) => { let title = $(item).find(.stitle .ticket-btn).attr(title); let score = $(item).find(.subject-rate).text().replace(/\n\s{1,}|\t/g, ""); let imgUrl = $(item).find(img).attr(src); //保存图片 saveImg(imgUrl,title); arr.push({ title, score, imgUrl }) }); // console.log(arr) }); //读取并保存图片至本地 function saveImg(url,name) { superagent.get(url).end(function(err, sres) { if (err) { console.log(err); return; } //通过fs将文件写入./image目录,以标题为图片名称 fs.writeFile(`./image/${name}.jpg`, sres.body, "binary", function(err) { if (err) throw err; console.log(`${name}图片保存完成`) }); }); }node-crawler (轻量级node爬虫工具)
node-crawler,完全由nodejs写成,天生支持非阻塞异步IO。
框架特点
DOM 元素快速解析 & 符合jQuery语法的选择器功能(默认使用Cheerio,支持更换为 JSDOM 等其它DOM解析器)支持连接池模式,并发数和重连数均可配置支持请求队列的优先权(即不同URL的请求能有不同的优先级)支持延时功能(代理ip获取某些服务器对每分钟内连接数有限制)支持 forceUTF8 模式以应对复杂的编码问题,当然你也可以自己为不同的连接设置编码支持4.x及更高版本的Nodejs1. 安装
npm install crawler
2. 可控制并发数量、启用慢速模式
var Crawler = require("crawler"); var c = new Crawler({ // 最大并发数默认为10 maxConnections : 1, // 两次请求之间将闲置1000ms rateLimit : 1, callback : function (error, res, done) { if(error){ console.log(error); }else{ var $ = res.$; console.log($("title").text()); } done(); } }); c.queue(http://www.amazon.com);用新框架实现爬取并下载图片,相关代码如下
var Crawler = require("crawler"); var fs = require(fs); //nodejs核心模块,用来处理数据流 var c = new Crawler({ encoding: null, // `maxConnections` 将被强制修改为 1 // maxConnections : 10, jQuery: false, // 两次请求之间将闲置1000ms // rateLimit: 1000, // 在每个请求处理完毕后将调用此回调函数 callback: function(error, res, done) { if (error) { console.log(error); } else { //将图片存放至image文件夹下 fs.createWriteStream(`./image/${res.options.filename}`).write(res.body); console.log(`${res.options.filename}图片保存完成`) } done(); } }); let arr = []; //去爬取 c.queue([{ uri: , jQuery: true, // 实例化时的callback不会被触发 callback: function(error, res, done) { if (error) { console.log(error); } else { var $ = res.$; //循环获取所需内容 $(#nowplaying .lists .list-item).each((index, item) => { let title = $(item).find(.stitle .ticket-btn).attr(title); let score = $(item).find(.subject-rate).text().replace(/\n\s{1,}|\t/g, ""); let imgUrl = $(item).find(img).attr(src); //请求图片,请求后会触发实例化时定义的回调函数 c.queue({ uri: imgUrl, filename: `${title}.png` }); arr.push({ title, score, imgUrl }) }); } done(); } }]);最后:
node实现爬虫基本介绍完毕,大家可以自己着手来开发一个自己的爬虫。