node.js 爬虫入门总结

node.js爬虫

前端同学可能向来对爬虫不是很感冒,觉得爬虫需要用偏后端的语言,诸如 php , python 等。当然这是在 nodejs 前了,nodejs 的出现,使得 Javascript 也可以用来写爬虫了。由于 nodejs 强大的异步特性,让我们可以轻松以异步高并发去爬取网站,当然这里的轻松指的是 cpu 的开销。

要读懂本文,其实只需要有

  • 能看懂 Javascript 及 JQuery
  • 简单的nodejs基础
  • http 网络抓包 和 URL 基础

Nodejs做爬虫的优劣

首先说一下node做爬虫的优势

第一个就是他的驱动语言是JavaScript。JavaScript在nodejs诞生之前是运行在浏览器上的脚本语言,其优势就是对网页上的dom元素进行操作,在网页操作上这是别的语言无法比拟的。

第二就是nodejs是单线程异步的。听起来很奇怪,单线程怎么能够异步呢?想一下学操作系统的时候,单核cpu为什么能够进行多任务处理?道理也是类似,在操作系统中进程对CPU的占有进行时间切片,每一个进程占有的时间很短,但是所有进程循环很多次,因此看起就像是多个任务在同时处理。js也是一样,js里有事件池,CPU会在事件池循环处理已经响应的事件,未处理完的事件不会放到事件池里,因此不会阻塞后续的操作。在爬虫上这样的优势就是在并发爬取页面上,一个页面未返回不会阻塞后面的页面继续加载,要做到这个不用像python那样需要多线程。

其次是node的劣势

首先是异步并发上。处理的好很方便,处理的不好就会很麻烦。例如要爬取10个页面,用node不做异步处理话,那返回的结果可不一定是按1、2、3、4……这个顺序,很可能是随机。解决的办法就是增加一个页面的序列戳,让爬取的数据生成csv文件,然后重新排序。

第二个是数据处理上的劣势,这点是不如python的,如果只是单纯的爬数据,用node当然很好,但是如果用爬来的数据继续做统计分析,做个回归分析聚类啥的话,那就不能用node一步到底了。

如何用nodejs做爬虫

下面就要说一下如何用nodejs做爬虫了

  • 1、初始化项目文件

在对应的项目文件夹下执行npm init来初始化一个package.json文件

  • 2、安装request和cheerio依赖包

request听起来很熟悉吧,跟python里request功能一样。它的功能就是建立起对目标网页的链接,并返回相应的数据,这个不难理解。

cheerio的功能是用来操作dom元素的,他可以把request返回来的数据转换成可供dom操作的数据,更重要的cheerio的api跟jquery一样,用$来选取对应的dom结点,是不很方便?对一个前端程序员来说,这比python的什么xpath和beautisoup方便了不知道多少啊哈哈

安装命令也很简单:

分别是npm install request --save 和 npm install cheerio

  • 3、引入依赖包并使用

接下来就用request , fs和cherrio写一个爬虫吧!

首先引入依赖模块

var http=require("http");        //网络请求var fs=require("fs");            //操作文件,读写文件var cheerio=require("cheerio");  //扩展模块注:cheerio 模块是第三方模块,需要进行安装:npm install cheerio --save

接下来就以我之前爬取的的百度新闻页为例吧,为什么要选这个呢,因为这个是最基础最简单的。

百度新闻页面链接是:http://news.baidu.com/

执行下面代码:

var http=require("http");
var fs=require("fs");const wz="http://news.baidu.com/"; //网址var strHtml="";
var results=[];
http.get(wz,function(res){res.on("data",function(chunk){strHtml+=chunk;})res.on("end",function(){console.log(strHtml);});
})

运行一下结果就是这样的

图片描述

是不是很激动哈哈,html返回回来了。这样还是不够的,接下就是要处理下返回的数据,并提炼出我们想要获得的信息,这就轮到cheerio登场了

将request返回的结果传入cheerio中,并获得想要获取的信息,看代码是不是想在写脚本的感觉?

接下来我们在获取一下这一段

图片描述

执行以下代码:

var http=require("http");var fs=require("fs");var cheerio=require("cheerio");const wz="http://news.baidu.com/";var strHtml="";
var results=[];
http.get(wz,function(res){res.on("data",function(chunk){strHtml+=chunk;})res.on("end",function(){//console.log(strHtml);var $=cheerio.load(strHtml);$("#channel-all li").each((iten,i)=>{console.log($(i).text());})});
})        

运行一下结果如下:

图片描述

这样一个简单的爬虫就完成啦,是不是很简单啊。

然后再简单的介绍一下node.js爬取图片

以下是我们将要爬取的图片:

图片描述

首先我们也需要同上面一样引入一些需要的核心模块

var http = require("http");var https = require("https");var fs = require("fs");var cheerio = require("cheerio");

注:cheerio 模块是第三方模块,需要进行安装:

npm install cheerio --save

//保存网络图片
function saveImage(imageUrl){http.get(imageUrl, function (res) {res.setEncoding('binary');      //二进制(binary)var imageData ='';res.on('data',function(data){  //图片加载到内存变量imageData += data;}).on('end',function(){        //加载完毕保存图片if(!fs.existsSync("./images")){fs.mkdirSync("./images");}fs.writeFile('images/'+Math.random()+'.png',imageData,'binary',function (err) {  //以二进制格式保存if(err) throw err;console.log('保存成功');});});});
}

图片描述

nodejs 爬虫总结

① http.get+cheerio+iconv-lite

这种方式还是比较简单的,容易理解,直接使用http的get方法进行请求url,将得到的内容给cheerio解析,用jquery的方式解析出我们要东西即可。

要点:

得到的结果中文乱码如何解决呢,用iconv-lite模块将得到的内容进行转码即可。

http.get(options,function(result){var body = [];result.on('data',function(chunk){body.push(chunk);});result.on('end', function () {var html = iconv.decode(Buffer.concat(body), 'gb2312');  //注意这里body是数组var $ = cheerio.load(html);...});
});

② request+cheerio+iconv-lite

这种方式在获取内容的方式上与上有些不同,可以直接获取到Buffer类型的数据。然后将得到的内容给cheerio解析,用jquery的方式解析出我们要东西即可。

要点:

结果中文乱码如何解决,用iconv-lite模块将得到的内容进行转码即可。

request(options,function(err,res,body){if(err)console.log(err);if(!err&&res.statusCode==200){var html = iconv.decode(body, 'gb2312');     //这里body是直接拿到的是Buffer类型的数据,可以直接解码。var $ = cheerio.load(html);...}
});

③ superagent+cheerio+superagent-charset

这种方式是比前面两个有较大差别,用了superagent的get方法发起请求,解码的时候用到了superagent-charse,用法还是很简单的,之后再将获取到的内容给cheerio解析,用jquery的方式解析出我们要东西即可。

要点:

结果中文乱码解决用superagent-charset模块进行转码,方式较之上面有点差别。

首先看它的加载方式:

var charset = require("superagent-charset");var superagent = charset(require("superagent"));   //将superagent模块传递给superagent-charset

解码方式:

superagent.get(url).charset('gb2312')                                //用charset方法达到解码效果。.end(function(err,result){if(err) console.log(err);var $ = cheerio.load(result.text);...});

至此呢,Nodejs爬虫的核心就已经介绍完毕了,剩下就完全可以自由发挥了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540477.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数组重复次数最多的元素递归_使用递归计算链接列表中元素的出现次数

数组重复次数最多的元素递归Solution: 解: Required function: 所需功能: func_occurence ( node *temp) //recursive functionInput: 输入: A singly linked list whose address of the first node is stored in a pointer, say head and…

SecureCRT中文乱码解决方法

服务端export LANGzh_CN.UTF-8客户端SecureCRT编码选择UTF-8客户端SecureCRT字体选择新宋体,字符集选择中文总结:客户端和服务端字符编码一致,客户端字体字符集支持转载于:https://blog.51cto.com/leomars/1972669

[转载] Python 迭代器 深入理解 与应用示例

参考链接: Python | 可迭代和迭代器之间的区别 本篇文章简单谈谈可迭代对象,迭代器和生成器之间的关系。 三者简要关系图 可迭代对象与迭代器 刚开始我认为这两者是等同的,但后来发现并不是这样;下面直接抛出结论: 1…

Python程序查找表示O(1)复杂度的数字所需的位数

Problem statement 问题陈述 Find total Number of bits required to represent a number in binary 查找以二进制表示数字所需的总位数 Example 1: 范例1: input : 10output: 4Example 2: 范例2: input : 32output : 6Formula used: 使用的公式&am…

正则split

string content "第1行导入失败,失败原因为: 《加班原因》字段必填";string[] resultString Regex.Split(content, "失败原因为:", RegexOptions.IgnoreCase);foreach (string i in resultString){Console.WriteLine(i…

将八进制数制转换为二进制,十进制和十六进制数制

1)将八进制数制转换为二进制数制 (1) Conversion of Octal Number System to Binary Number System) To convert octal numbers into binary numbers, we can use the relationship between octal and binary numbers. 要将八进制数转换为二进制数,我们可以使用八进…

[转载] Python的生成器

参考链接: Python中的生成器Generator Python的生成器 什么是生成器 创建python迭代器的过程虽然强大,但是很多时候使用不方便。生成器是一个简单的方式来完成迭代。简单来说,Python的生成器是一个返回可以迭代对象的函数。 怎样创建生…

想提高用户访问的响应速度和成功率还不赶快学习CDN

2019独角兽企业重金招聘Python工程师标准>>> 课程介绍 CDN可以将源站内容分发至最接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率。解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点加速、点…

[转载] python迭代器、生成器和装饰器

参考链接: 有效地在Python中使用迭代 文章目录 生成器生成器表达式(generator expression)通过使用yield关键字定义生成器并行前戏高潮 迭代器迭代器概述iter()函数 创建迭代器创建一个迭代器(类)内置迭代器工具count无限迭代器cycle 无限迭代器,从一个…

java中的starts_Java Math类静态double nextAfter(double starts,double direction)示例

java中的starts数学类静态double nextAfter(双向启动,双向) (Math Class static double nextAfter(double starts , double directions) ) This method is available in java.lang package. 此方法在java.lang包中可用。 This method is used to return the double …

Python 核心编程(第二版)——条件和循环

Python 中的 if 子句由三部分组成: 关键字本身,用于判断结果真假的条件表达式, 以及当表达式为真或者非零时执行的代码块。if 语句的语法如下: if expression: expr_true_suite 单个 if 语句可以通过使用布尔操作符 and , or 和 not实现多重判断条件或…

[转载] 【python魔术方法】迭代器(__iter__和__next__)

参考链接: Python __iter __()和__next __()| 将对象转换为迭代器 文章目录 __iter__ 和 __next__真正的迭代器总结 python里面有很多的以__开始和结尾的函数,利用它们可以完成很多复杂的逻辑代码,而且提高了代码的简洁性,本文主…

Silverlight 异步单元测试

Silverlight 中的很多操作都是异步的,很多情况下要求单元测试也是异步的,但是介绍异步单元测试的文档很少。通过对 Silverlight Toolkit 中的 Microsoft.Silverlight.Testing 和 Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight 这两个文件…

网络拓扑 令牌环网 以太网_以太网连接中网络拓扑的类型及其框架 以太网技术...

网络拓扑 令牌环网 以太网A topology explains how physically the network is designed or what is the structure of the network. These designs are both physical and logical. There are many network topologies 4 like Bus, Star, Ring, and Mesh. But only two types …

Wafer晶圆封装工艺介绍

芯片封装的目的(The purpose of chip packaging): 芯片上的IC管芯被切割以进行管芯间连接,通过引线键合连接外部引脚,然后进行成型,以保护电子封装器件免受环境污染(水分、温度、污染物等)&…

[转载] Python中的解析式和生成器表达式

参考链接: Python | 生成器表达式 解析式和生成器表达式 列表解析List Comprehension 语法 [返回值 for 元素 in 可迭代对象 if 条件]使用中括号[],内部是for循环,if条件语句可选,会返回一个新的列表 列表解析试优点 编译器会优化&…

java 数字字母进位_使用带有进位的8085微处理器将两个8位数字相乘

java 数字字母进位Problem statement: 问题陈述: Multiplication of two 8 bits numbers using 8085 microprocessor with carry. 使用带有进位的8085微处理器将两个8位数字相乘。 Algorithm: 算法: Load HL pair with initial data using LHLD comma…

[转载] Python3.0中普通方法、类方法和静态方法的比较

参考链接: Python中的类方法与静态方法 一、语法区别 刚接触Python中的面向对象,对于类方法和静态方法难以区分,通过查找知乎、CSDN论坛,废了好大的劲思路才逐渐明朗,所以就总结顺便分享一下。 首先开始编辑代码 # 普…

iOS:个人浅谈工厂模式

一、什么是工厂方法? 正式的解释是:在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行。工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好地符合了…

scanf 输入十六进制_使用C语言中的scanf()在字符变量中输入十进制,八进制和十六进制值...

scanf 输入十六进制Here, we will declare an unsigned char variable and input different formats value like decimal format, octal format and hexadecimal format. 在这里,我们将声明一个无符号的char变量,并输入不同格式的值,例如十进…