nodejs制作爬虫实现批量下载图片

今天想获取一大批猫的图片,然后就在360流浪器搜索框中输入 ,然后点击图片。就看到了一大波猫的图片: http://image.so.com/i?q=%E7%8... ,我在想啊,要是审查元素,一张张手动下载,多麻烦,所以打算写程序来实现。不写不知道,一写发现里面还是有很多道道的。

nodejs制作爬虫实现批量下载图片

1. 爬取图片链接

因为之前也写过nodejs爬虫功能(参见:NodeJS制作爬虫全过程),所以觉得应该很简单,就用cheerio来处理dom啦,结果打印一下啥也没有,后来查看源代码:

nodejs制作爬虫实现批量下载图片

发现 waterfall_zoom 里面空空如也,查找了一下,发现所有的数据都是写在 <script> 里面,然后动态加载到页面的,所以用cheerio.load到的页面里面其实没数据的。真实数据:

nodejs制作爬虫实现批量下载图片

分析完毕,刷刷写代码:

var request = require('request');
var cheerio = require('cheerio');
var url = 'http://image.so.com/i?q=%E7%8C%AB&src=tab_www';

request(url,function(err,res,body){
  if(!err && res.statusCode === 200){
    var $ = cheerio.load(body);
    var imgList = []
    JSON.parse($('script[id="initData"]').html()).list.forEach(function(item){
      imgList.push(item.img)
    });
    console.log(imgList);
  }
});

nodejs制作爬虫实现批量下载图片

2. 下载图片到本地 2.1 粗糙的方案

最初的思路很简单,简单的 fs.createWriteStream() 就能解决:

var downloadPic = function(src, dest){
  request(src).pipe(fs.createWriteStream(dest)).on('close',function(){
    console.log('pic saved!')
  })
}

使用方式:

downloadPic(imgList[0],'./catpics/1.jpg');

nodejs制作爬虫实现批量下载图片

成功捕获一只猫!然后写了一个循环准备捕获所有猫。然而这种方式是串行的,速度很慢!下载一大批图片要花大量时间。

2.2 使用async异步批量下载

关于async的map操作,详见: async_demo/map.js ,对集合中的每一个元素,执行某个异步操作,得到结果。所有的结果将汇总到最终的callback里。与forEach的区别是,forEach只关心操作不管最后的值,而map关心的最后产生的值。

提供了两种方式:

并行执行。 async.map 同时对集合中所有元素进行操作,结果汇总到最终callback里。如果出错,则立刻返回错误以及已经执行完的任务的结果,未执行完的占个空位

顺序执行。 async.mapSeries 对集合中的元素一个一个执行操作,结果汇总到最终callback里。如果出错,则立刻返回错误以及已经执行完的结果,未执行的被忽略。

在此处:

async.mapSeries(imgList,function(item, callback){
  setTimeout(function(){
    downloadPic(item, './catpics/'+ (new Date()).getTime() +'.jpg');
    callback(null, item);
  },400);
}, function(err, results){});

注: 此处使用setTimeout,是因为下载需要一定时间,在笔者较慢网速下,需要400ms的间隔能确保每张图片下载完全。

nodejs制作爬虫实现批量下载图片

成功捕获一批猫猫!

2.3 使用bagpipe批量

bagpipe 是朴灵大大做的一个在nodejs中控制并发执行的模块。其安装和使用也比较简单:

npm install bagpipe --save

使用:

var Bagpipe = require('bagpipe');

var bagpipe = new Bagpipe(10);
var files = ['这里有很多很多文件'];
for(vari =0; i < files.length; i++){
  bagpipe.push(fs.readFile, files[i], 'utf-8',function(err, data){
    ...
  });
}

在此处:

var bagpipe = new Bagpipe(10,{timeout: 100});
for(var i = 0; i < imgList.length; i++) {
  console.log('i:'+i)
  bagpipe.push(downloadPic, imgList[i], './catpics/'+ i +'.jpg', function(err, data){
    //
   });
}

3.总结

作为一个程序员,能用程序解决就不手动解决。每一次尝都会有新的收获。

时间: 2017-05-18

NodeJS制作爬虫全过程(续)

书接上回,我们需要修改程序以达到连续抓取40个页面的内容.也就是说我们需要输出每篇文章的标题.链接.第一条评论.评论用户和论坛积分. 如图所示,$('.reply_author').eq(0).text().trim();得到的值即为正确的第一条评论的用户. {<1>} 在eventproxy获取评论及用户名内容后,我们需要通过用户名跳到用户界面继续抓取该用户积分 复制代码 代码如下: var $ = cheerio.load(topicHtml); //此URL为下一步抓取目标URL var

nodeJs爬虫获取数据简单实现代码

本文实例为大家分享了nodeJs爬虫获取数据代码,供大家参考,具体内容如下 var http=require('http'); var cheerio=require('cheerio');//页面获取到的数据模块 var url='http://www.jcpeixun.com/lesson/1512/'; function filterData(html){ /*所要获取到的目标数组 var courseData=[{ chapterTitle:"", videosData:{ v

nodejs爬虫遇到的乱码问题汇总

上一篇文章中使用nodejs程序解析了网页编码为gbk,gb2312,以及utf-8的情况,这里面有三种特殊的乱码情况需要单独的说明一下. 1,网页编码为utf-8,但是解析为乱码,代表网站为www.guoguo-app.com. 这个问题真是个逗逼问题,查看网页源码中给出的编码方式为utf8,如下: <meta charset="UTF-8"> <title>查快递</title> 由于解析出来的始终是乱码,我就抓包看了下,报文中的编码方式为gbk

NodeJS制作爬虫全过程

今天来学习alsotang的爬虫教程,跟着把CNode简单地爬一遍. 建立项目craelr-demo 我们首先建立一个Express项目,然后将app.js的文件内容全部删除,因为我们暂时不需要在Web端展示内容.当然我们也可以在空文件夹下直接 npm install express来使用我们需要的Express功能. 目标网站分析 如图,这是CNode首页一部分div标签,我们就是通过这一系列的id.class来定位我们需要的信息. 使用superagent获取源数据 superagent就是

nodejs爬虫抓取数据乱码问题总结

一.非UTF-8页面处理. 1.背景 windows-1251编码 比如俄语网站:https://vk.com/cciinniikk 可耻地发现是这种编码 所有这里主要说的是 Windows-1251(cp1251)编码与utf-8编码的问题,其他的如 gbk就先不考虑在内了~ 2.解决方案 1. 使用js原生编码转换 但是我现在还没找到办法哈.. 如果是utf-8转window-1251还可以http://stackoverflow.com/questions/2696481/encoding

详解nodejs爬虫程序解决gbk等中文编码问题

使用nodejs写了一个爬虫的demo,目的是提取网页的title部分. 遇到最大的问题就是网页的编码与nodejs默认编码不一致造成的乱码问题.nodejs支持utf8, ucs2, ascii, binary, base64, hex等编码方式,但是对于汉语言来说编码主要分为三种,utf-8,gb2312,gbk.这里面gbk是完全兼容gb2312的,因此在处理编码的时候主要就分为utf-8以及gbk两大类.(这是在没有考虑到其他国家的编码情况,比如日本的Shift_JIS编码等,同时这里这

Nodejs爬虫进阶教程之异步并发控制

之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回答才会再加载一部分,所以说如果直接发送一个问题的请求链接,取得的页面是不完整的.还有就是我们通过发送链接下载图片的时候,是一张一张来下的,如果图片数量太多的话,真的是下到你睡完觉它还在下,而且我们用nodejs写的爬虫,却竟然没有用到nodejs最牛逼的异步并发的特性,太浪费了啊. 思路 这次的的爬虫是上次那个的升级版,不过呢,上次那个虽

简单好用的nodejs 爬虫框架分享

这个就是一篇介绍爬虫框架的文章,开头就不说什么剧情了.什么最近一个项目了,什么分享新知了,剧情是挺好,但介绍的很初级,根本就没有办法应用,不支持队列的爬虫,都是耍流氓. 所以我就先来举一个例子,看一下这个爬虫框架是多么简单并可用. 第一步:安装 Crawl-pet nodejs 就不用多介绍吧,用 npm 安装 crawl-pet $ npm install crawl-pet -g --production 运行,程序会引导你完成配置,首次运行,会在项目目录下生成 info.json 文件 $

nodejs爬虫抓取数据之编码问题

cheerio DOM化并解析的时候 1.假如使用了 .text()方法,则一般不会有html实体编码的问题出现 2.如果使用了 .html()方法,则很多情况下(多数是非英文的时候)都会出现,这时,可能就需要转义一番了 类似这些 因为需要作数据存储,所有需要转换 复制代码 代码如下: Халк крушит. Новый способ исполнен 大多数都是&#(x)?\w+的格式 所以就用正则转换一番 var body = ....//这里就是请求后获得的返回数据,或者那些 .html

nodeJS实现简单网页爬虫功能的实例(分享)

本文将使用nodeJS实现一个简单的网页爬虫功能 网页源码 使用http.get()方法获取网页源码,以hao123网站的头条页面为例 http://tuijian.hao123.com/hotrank var http = require('http'); http.get('http://tuijian.hao123.com/hotrank',function(res){ var data = ''; res.on('data',function(chunk){ data += chunk;

基于nodejs 的多页面爬虫实例代码

前言 前端时间再回顾了一下node.js,于是顺势做了一个爬虫来加深自己对node的理解. 主要用的到是request,cheerio,async三个模块 request 用于请求地址和快速下载图片流. https://github.com/request/request cheerio 为服务器特别定制的,快速.灵活.实施的jQuery核心实现. 便于解析html代码. https://www.npmjs.com/package/cheerio async 异步调用,防止堵塞. http://

使用Ajax局部更新Razor页面的实例代码

Razor功能非常强大,但是本身并不能做到无刷新,所以需要配合ajax使用 本文就做一个简单例子,实现Razor配合ajax做到局部刷新. 首先,我们创建一个MVC项目 让我们创建一个简单的Controller Book 然后对其添加一个视图,并且添加上一些简单的Html代码 @{ ViewBag.Title = "Index"; Layout = null; } <!DOCTYPE html> <html> <head> <meta http

新手vue构建单页面应用实例代码

本文介绍了新手vue构建单页面应用实例代码,分享给大家,具体如下 步骤: 1.使用vue-cli创建项目 2.使用vue-router实现单页路由 3.用vuex管理我们的数据流 4.使用vue-resource请求我们的node服务端 5.使用.vue文件进行组件化的开发 一.目录结构: 二.搭建项目 先安装 vue-cli: sudo npm install -g vue-cli 使用vue-cli构建初始化项目:vue init webpack project(创建webpack项目并下载

Session过期后自动跳转到登录页面的实例代码

最近做了一个项目其中有需求,要实现自动登录功能,通过查阅相关资料,打算用session监听来做,下面给大家列出了配置监听器的方法: 1.在项目的web.xml文件中添加如下代码: <!--添加Session监听器--> <listener> <listener-class> 监听器路径 </listener-class> </listener> 2.编写java类. public class SessionListener implements

SpringBoot创建JSP登录页面功能实例代码

添加JSP配置 1.pom.xml添加jsp解析引擎 <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.s

el表达式 写入bootstrap表格数据页面的实例代码

el表达式,写入bootstrap表格,简化代码,效果图: 不多说,上干货: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.

基于JavaScript实现回到页面顶部动画代码

最近做的都是前端的项目,很多项目都有回到顶部的需求,下面把我写js代码做个笔录,方便以后查找. 发现还可以添加从快到慢的动画效果和随时下拉滚动条停止滚动的功能, 参考了imooc上相关课程,最终实现JS代码如下: //页面加载后触发 window.onload = function(){ var btn = document.getElementById('btn'); var timer = null; var isTop = true; //获取页面可视区高度 var clientHeigh

基于JS实现bookstore静态页面的实例代码

先给大家展示下效果图,如果感觉还不错,请参考实现代码: bookstore静态页面代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> #right{ float: right; vertical-align: middle; line-height:50px; margin-right:70

nodejs 终端打印进度条实例代码

1. 场景导入 当我们对大量文件进行批量处理的时候(例如:上传/下载.保存.编译等),常常希望知道当前进展如何,或者失败(成功)的任务有多少:当我们的代码或程序已经发布,用户在执行安装的过程中,一个合适的(终端/命令行)进度条可以准确反映安装的步骤和进程,提升程序的可用性,一定程度缓解用户在等待中的烦恼-- 2. 基本原理 首先,在终端打印出文本是件比较容易的事情.那么使用简单的文本和符号,就够自己拼凑出命令行的效果(下面例子): 文件已上传: 43.60% ██████████████████

基于Python实现的扫雷游戏实例代码

本文实例借鉴mvc模式,核心数据为model,维护1个矩阵,0表无雷,1表雷,-1表已经检测过. 本例使用python的tkinter做gui,由于没考虑可用性问题,因此UI比较难看,pygame更有趣更强大更好看,做这些小游戏更合适,感兴趣的读者可以尝试一下! 具体的功能代码如下: # -*- coding: utf-8 -*- import random import sys from Tkinter import * class Model: """ 核心数据类,维护一