Node.js   发布时间:2022-04-24  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了node.js使用cheerio制作网络爬虫大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

打算要写一个公开课网站,缺少数据,就决定去网易公开课去抓取一些数据。

前一阵子看过一段时间的Node.js,而且Node.js也比较适合做这个事情,就打算用Node.js去抓取数据。

关键是抓取到网页之后如何获取到想要的数据呢?然后就发现了cheerio,用来解析html非常方便,就像在浏览器中使用jquery一样。

使用如下命令安装cheerio

     npm install cheerio@H_607_15@@H_607_15@

Cheerio安装完成, 我们就可以开始工作了。 首先让我们来看一段javascript代码 这段代码可以下载任意一个网页的内容。将其放入到curl.js中,并导出。@H_607_15@

node.js使用cheerio制作网络爬虫

@H_607_15@
var@H_607_15@ http = @R_874_10613@ire("http");
 
@H_607_15@//@H_607_15@ Utility function that downloads a URL and invokes@H_607_15@
//@H_607_15@ callBACk with the data.@H_607_15@
function@H_607_15@ download(url,callBACk) {
  http.get(url,@H_607_15@function@H_607_15@(res) {
    @H_607_15@var@H_607_15@ data = "";
    res.on(@H_607_15@'data',function@H_607_15@ (chunk) {
      data @H_607_15@+= chunk;
    });
    res.on(@H_607_15@"end",255); line-height:1.5!important">function() {
      callBACk(data);
    });
  }).on(@H_607_15@"error",255); line-height:1.5!important">function() {
    callBACk(@H_607_15@null@H_607_15@);
  });
}

exports.download @H_607_15@= download;

node.js使用cheerio制作网络爬虫

@H_607_15@

然后是使用cheerio解析html,找到想要的数据。

我们先来自己分析一下页面。我们要抓取http://v.163.com/special/opencourse/englishs1.html这个页面中的视频,视频的地址都在下载的按钮里。其中一个下载按钮的html的代码如下:

<@H_607_15@a @H_607_15@class@H_607_15@="downbtn"@H_607_15@ href@H_607_15@="http://mov.bn.netease.com/mobilev/2013/1/F/G/S8KTEF7FG.mp4"@H_607_15@ id@H_607_15@="M8KTEKR84"@H_607_15@ target@H_607_15@="_blank"@H_607_15@></@H_607_15@a@H_607_15@>@H_607_15@

我们取到其中的href属性,只需要进行如下选择即可

$("a.downbtn").attr("href");

在是现实,我们可以在index.js中写入如下代码

var cheerio = @R_874_10613@ire("cheerio"); @H_607_15@var@H_607_15@ server = @R_874_10613@ire("./curl"); @H_607_15@var@H_607_15@ url = "http://v.163.com/special/opencourse/englishs1.html" server.download(url,255); line-height:1.5!important">function@H_607_15@(data) { @H_607_15@if@H_607_15@ (data) { @H_607_15@console.log(data);@H_607_15@ var@H_607_15@ $ = cheerio.load(data); $(@H_607_15@"a.downbtn").each(function@H_607_15@(i,E) { console.log($(E).attr(@H_607_15@"href")); }); console.log(@H_607_15@"done"); } @H_607_15@else@H_607_15@ { console.log(@H_607_15@"error"); } });@H_607_15@

node.js使用cheerio制作网络爬虫

@H_607_15@

后执行

     node index.js@H_607_15@

这样就可以在命令框里面打印出页面上所有的视频地址。如下图

node.js使用cheerio制作网络爬虫

 

cheerio中文API [参考]@H_618_174@

我们将用到的标记示例

ul id@H_607_15@="fruits"@H_607_15@>@H_607_15@ li @H_607_15@="apple"@H_607_15@>@H_607_15@Apple</@H_607_15@li@H_607_15@="orange"@H_607_15@>@H_607_15@Orange="pear"@H_607_15@>@H_607_15@Pear>@H_607_15@ ul@H_607_15@ 这是我们将会在所有的API例子中用到的HTML标记@H_607_15@

Loading

首先你需要加载HTML。这一步对jQuery来说是必须的,since jQuery operates on the one,baked-in DOM。通过Cheerio,我们需要把HTML document 传进去。

这是首选@H_607_15@:

var
@H_607_15@ cheerio =@R_874_10613@ire('cheerio'),$ @H_607_15@= cheerio.load('<ul id="fruits">...</ul>');

或者通过传递字符串作为内容来加载HTML:@H_607_15@

$ =@R_874_10613@ire('cheerio');
$(@H_607_15@'ul','<ul id="fruits">...</ul>');

Or as the root:@H_607_15@

$ =@R_874_10613@ire('cheerio');
$(@H_607_15@'li','ul',sans-serif; font-size:13.920000076293945px"> 你也可以传递一个额外的对象给.load()如果你需要更改任何的认解析选项的话:@H_607_15@

$ = cheerio.load('<ul id="fruits">...</ul>',{
    ignoreWhitespace:@H_607_15@true@H_607_15@,xmlmode:@H_607_15@true@H_607_15@});

这些解析选项都是直接来自htmlparser ,因此任何在htmlparser里有效的选项在Chreeio里也是行得通的。认的选项如下:@H_607_15@

{
    ignoreWhitespace:@H_607_15@false@H_607_15@,lowerCaseTags:@H_607_15@false@H_607_15@
}@H_607_15@

SELEctors

Cheerio的选择器用起来几乎和jQuery一样,所以API也很相似。

$(SELEctior,[context],[root])@H_607_15@

选择器在 Context 范围内搜索,Context又在Root范围内搜索SELEctor 和context可是是一个字符串表达式,DOM元素,和DOM元素的数组,或者chreeio对象。root 是通常是HTML 文档字符串。

node.js使用cheerio制作网络爬虫

@H_607_15@
$('.apple','#fruits').text()
@H_607_15@=> Apple@H_607_15@

$(@H_607_15@'ul .pear').attr('class')
@H_607_15@=> pear@H_607_15@

$(@H_607_15@'lI[class=orange]').html()
@H_607_15@=> <li class="orange">Orange</li>@H_607_15@

node.js使用cheerio制作网络爬虫

@H_607_15@

Attributes

获得和修改属性

.attr(name,value)@H_607_15@

获得和修改属性。在匹配的元素中只能获得第一元素的属性。如果设置一个属性的值为null,则移除这个属性。你也可以传递一对键值,或者一个函数

$('ul').attr('id')
@H_607_15@=> fruits@H_607_15@

$(@H_607_15@'.apple').attr('id','favorite').html()
@H_607_15@=> <li class="apple" id="favorite">Apple</li>@H_607_15@

.val([value])@H_607_15@

获得和修改input,SELEct,textarea的value.注意: 对于传递键值和函数支持还没有被加进去。

$('input[type="text"]').val()
@H_607_15@=> input_text@H_607_15@

$(@H_607_15@'input[type="text"]').val('test').html()
@H_607_15@=><input type="text" value="test"/>@H_607_15@

.removeAttr(Name)@H_607_15@

通过name删除属性

$('.pear').removeAttr('class').html()
@H_607_15@=> <li>Pear</li>@H_607_15@

.hasClass( className )@H_607_15@@H_607_15@

检查匹配的元素是否有给出的类名

node.js使用cheerio制作网络爬虫

@H_607_15@
$('.pear').hasClass('pear')
@H_607_15@=> true@H_607_15@

$(@H_607_15@'apple').hasClass('fruit')
@H_607_15@=> false@H_607_15@

$(@H_607_15@'li').hasClass('pear')
@H_607_15@=> true@H_607_15@

node.js使用cheerio制作网络爬虫

@H_607_15@

.addClass(className)@H_607_15@

增加class(es)给所有匹配的elements.也可以传函数

$('.pear').addClass('fruit').html()
@H_607_15@=> <li class="pear fruit">Pear</li>@H_607_15@

$(@H_607_15@'.apple').addClass('fruit red').html()
@H_607_15@=> <li class="apple fruit red">Apple</li>@H_607_15@

.removeClass([className])@H_607_15@

从选择的elements里去除一个或多个有空格分开的class。如果className 没有定义,所有的classes将会被去除,也可以传函数

$('.pear').removeClass('pear').html()
@H_607_15@=> <li class="">Pear</li>@H_607_15@

$(@H_607_15@'.apple').addClass('red').removeClass().html()
@H_607_15@=> <li class="">Apple</li>@H_607_15@

.toggleClass( className,[switch] )@H_607_15@@H_607_15@

添加删除class,依赖于当前是否有该class.

$('.apple.green').toggleClass('fruit green red').html()
@H_607_15@=> <li class="apple fruit red">Apple</li>@H_607_15@

$(@H_607_15@'.apple.green').toggleClass('fruit green red',255); line-height:1.5!important">true).html()
@H_607_15@=> <li class="apple green fruit red">Apple</li>@H_607_15@

.is( SELEctor )@H_607_15@@H_607_15@

.is( element )@H_607_15@

.is( SELEction )@H_607_15@

.is( function(indeX) )@H_607_15@

有任何元素匹配SELEctor就返回true。如果使用判定函数,判定函数在选中的元素中执行,所以this指向当前的元素。

Traversing

.find(SELEctor)@H_607_15@

获得一个在匹配的元素中由选择器滤过的后代。

$('#fruits').find('li').length
@H_607_15@=> 3@H_607_15@

.parent([SELEctor])@H_607_15@@H_607_15@

获得每个匹配元素的parent,可选择性的通过SELEctor筛选。

$('.pear').parent().attr('id')
=> fruits@H_607_15@

.parents([SELEctor])@H_607_15@

获得通过选择器筛选匹配的元素的parent集合。

$('.orange').parents().length
@H_607_15@ => 2@H_607_15@
$('.orange').parents('#fruits').length
@H_607_15@ => 1@H_607_15@

.closest([SELEctor])@H_607_15@@H_607_15@

对于每个集合内的元素,通过测试这个元素和DOM层级关系上的祖先元素,获得第一个匹配的元素

$('.orange').closest() => []@H_607_15@
$('.orange').closest('.apple') => []@H_607_15@
$('.orange').closest('li') => [<li class="orange">Orange</li>]@H_607_15@
$('.orange').closest('#fruits') => [<ul id="fruits"> ... </ul>]@H_607_15@

.next()@H_607_15@@H_607_15@

获得第一个本元素之后的同级元素

$('.apple').next().hasClass('orange')
=> true@H_607_15@

.nextAll()@H_607_15@

获得本元素之后的所有同级元素

$('.apple').nextAll()
@H_607_15@=> [<li class="orange">Orange</li>,<li class="pear">Pear</li>]@H_607_15@

.prev()@H_607_15@@H_607_15@

获得本元素之前的第一个同级元素

$('.orange').prev().hasClass('apple')
@H_607_15@ .preAll()@H_607_15@

$('.pear').prevAll()
@H_607_15@@H_607_15@
@H_607_15@

获得本元素前的所有同级元素@H_607_15@

.slice(start,[end])@H_607_15@

获得选定范围内的元素

$('li').slice(1).eq(0).text()
@H_607_15@=> 'Orange'@H_607_15@

$(@H_607_15@'li').slice(1,2).length
@H_607_15@=> 1@H_607_15@

.siblings(SELEctor)@H_607_15@@H_607_15@

获得被选择的同级元素,不包括本身

$('.pear').siblings().length
@H_607_15@=> 2@H_607_15@

$(@H_607_15@'.pear').siblings('.orange').length
@H_607_15@ .children(SELEctor)@H_607_15@@H_607_15@

获被选择元素的子元素

$('#fruits').children().length
@H_607_15@=> 3@H_607_15@

$(@H_607_15@'#fruits').children('.pear').text()
@H_607_15@=> Pear@H_607_15@

.each(function(index,element))@H_607_15@@H_607_15@

迭代一个cheerio对象,为每个匹配元素执行一个函数。When the callBACk is fired,the function is fired in the context of the DOM element,so this refers to the current element,which is equivalent to the function parameter element.要提早跳出循环,返回false.

var
@H_607_15@ fruits =[]; $(@H_607_15@'li').each(:rgb(0,elem){ fruits[i]@H_607_15@= $(this@H_607_15@).text();}); fruits.join(@H_607_15@','); @H_607_15@=> Apple,Orange,Pear@H_607_15@

node.js使用cheerio制作网络爬虫

@H_607_15@

.map(function(index,sans-serif; font-size:13.920000076293945px"> 迭代一个cheerio对象,为每个匹配元素执行一个函数。Map会返回一个迭代结果的数组。the function is fired in the context of the DOM element,which is equivalent to the function parameter element

$('li').map(:rgb(0,el){
@H_607_15@ this === el@H_607_15@
return@H_607_15@ $(this@H_607_15@).attr('class');
}).join(@H_607_15@',0); line-height:1.5!important">=> apple,orange,pear
@H_607_15@

.filter(SELEctor)@H_607_15@@H_607_15@

.filter(function(indeX))@H_607_15@

迭代一个cheerio对象,滤出匹配选择器或者是传进去的函数的元素。如果使用函数方法,这个函数在被选择的元素中执行,所以this指向的手势当前元素。

SELEctor:

$('li').filter('.orange').attr('class');
@H_607_15@=> orange@H_607_15@

Function:@H_607_15@

$('li').filter(this@H_607_15@).attr('class')==='orange';
}).attr(@H_607_15@'class')
@H_607_15@ .first()@H_607_15@@H_607_15@

会选择chreeio对象的第一个元素

$('#fruits').children().first().text()
@H_607_15@=> Apple@H_607_15@

.last()@H_607_15@

$('#fruits').children().last().text()
@H_607_15@ 会选择chreeio对象的最后一个元素@H_607_15@

.eq(i)@H_607_15@

通过索引筛选匹配的元素。使用.eq(-i)就从最后一个元素向前数。

$('li').eq(0).text()
@H_607_15@=> Apple@H_607_15@

$(@H_607_15@'li').eq(-1).text()
@H_607_15@=> Pear@H_607_15@

@H_79_805@manipulation@H_607_15@

改变DOM结构的方法

.append(content,[content...])@H_607_15@

在每个元素最后插入一个子元素

node.js使用cheerio制作网络爬虫

@H_607_15@
$('ul').append('<li class="plum">Plum</li>')
$.html()
@H_607_15@=>  <ul id="fruits">@H_607_15@      <li class="apple">Apple</li>@H_607_15@      <li class="orange">Orange</li>@H_607_15@      <li class="pear">Pear</li>@H_607_15@      <li class="plum">Plum</li>@H_607_15@    </ul>@H_607_15@

node.js使用cheerio制作网络爬虫

@H_607_15@

.prepend(content,[content,...])@H_607_15@@H_607_15@

在每个元素最前插入一个子元素

node.js使用cheerio制作网络爬虫

@H_607_15@
$('ul').prepend('<li class="plum">Plum</li>')
$.html()
@H_607_15@ .after(content,...])@H_607_15@

在每个匹配元素之后插入一个元素

node.js使用cheerio制作网络爬虫

@H_607_15@
$('.apple').after('<li class="plum">Plum</li>')
$.html()
@H_607_15@ .before(content,sans-serif; font-size:13.920000076293945px"> 在每个匹配的元素之前插入一个元素

node.js使用cheerio制作网络爬虫

@H_607_15@
$('.apple').before('<li class="plum">Plum</li>')
$.html()
@H_607_15@ .remove( [SELEctor] )@H_607_15@

从DOM中去除匹配的元素和它们的子元素。选择器用来筛选要删除的元素。

$('.pear').remove()
$.html()
@H_607_15@    </ul>@H_607_15@

.replaceWith( content )@H_607_15@

替换匹配的的元素

var
@H_607_15@ plum = $('<li class="plum">Plum</li>') $(@H_607_15@'.pear').replaceWith(plum) $.html() @H_607_15@=> <ul id="fruits">@H_607_15@ <li class="apple">Apple</li>@H_607_15@ <li class="orange">Orange</li>@H_607_15@ <li class="plum">Plum</li>@H_607_15@ </ul>@H_607_15@

node.js使用cheerio制作网络爬虫

@H_607_15@

.empty()@H_607_15@

清空一个元素,移除所有的子元素

$('ul').empty()
$.html()
@H_607_15@=>  <ul id="fruits"></ul>@H_607_15@

.html( [htmlString] )@H_607_15@

获得元素的HTML字符串。如果htmlString有内容的话,将会替代原来的HTML

$('.orange').html()
@H_607_15@=> Orange@H_607_15@

$(@H_607_15@'#fruits').html('<li class="mango">Mango</li>').html()
@H_607_15@=> <li class="mango">Mango</li>@H_607_15@

.text( [textString] )@H_607_15@@H_607_15@

获得元素的text内容包括子元素。如果textString被指定的话,每个元素的text内容都会被替换。

node.js使用cheerio制作网络爬虫

@H_607_15@
$('.orange').text()
@H_607_15@=> Orange@H_607_15@

$(@H_607_15@'ul').text()
@H_607_15@=>  Apple@H_607_15@    Orange@H_607_15@    Pear@H_607_15@

node.js使用cheerio制作网络爬虫

@H_607_15@

Rendering

如果你想呈送document,你能使用html多效用函数

$.html()
@H_607_15@ 如果你想呈送outerHTML,你可以使用 $.html(SELEctor)

$.html('.pear')
@H_607_15@=> <li class="pear">Pear</li>@H_607_15@

By default,html will leave some tags open. Sometimes you may instead want to render a valid XML document. For example,you might parse the following XML snippet:@H_607_15@

$ = cheerio.load('<media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>');

... and later want to render to XMl. To do this,you can use the 'xml' utility function:@H_607_15@

$.xml()=>  <media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>@H_607_15@

@H_79_805@miscellaneous@H_607_15@

不属于其它地方的DOM 元素方法

.toArray()@H_607_15@

取得所有的在DOM元素,转化为数组、

$('li').toArray()
@H_607_15@=> [ {...},{...},{...} ]@H_607_15@

.clone()@H_607_15@

克隆cheerio对象

var
@H_607_15@ moreFruit = $('#fruits').clone()

Utilities@H_607_15@

$.root@H_607_15@

Sometimes you need to work with the top-level root element. To query it,you can use $.root().

$.root().append('<ul id="vegetables"></ul>').html();
@H_607_15@=> <ul id="fruits">...</ul><ul id="vegetables"></ul>@H_607_15@

$.contains( container,contained )@H_607_15@

查看cotained元素是否是container元素的子元素

$.parseHTML( data [,context ] [,keepScripts ] )@H_607_15@

将字符串解析为DOM节点数组。context参数对chreeio没有意义,但是用来维护APi的兼容性。

 

今天就到这里了~~有机会把前面的小程序完善成一个网页爬虫~~

本图文内容来源于网友网络收集整理提供,作为学习参使用,版权属于原作者。

猜你在找的Node.js相关文章

一、概述简介node.js实际上是采用google的chrome浏览器V8引擎,由C++编写的javascript运行环境,由于封装和底层的处理赋予了更大的能力,使得js可以像java、PHP等一样运行于服务器端。它可以像浏览器引擎那样解析js代码,却没有浏览器端各种安全性的限制,还提供许多系统级别的API: 1、文件的读写 2、进行的管理 3、网络通信Node.js与浏览器执行环境的异同点相
一、app.use与http.createServer….二、app.use路由与app.get、app.post#等等的区别针对不同的请求,Express提供了use方法的一些别名(get、post之类),用express时才能用get、post吗?三、express三大核心概念:路由、中间件、模板引擎四、要选择哪种模板比较好?
代码在 ==》E:nodes实战myservetestserve 1 express搭建后端请求路由,前端进行访问对应的接口 1) 创建项目目录 express 项目名 -e 然后按照提示就可以
1. fs读取文件 const fs=@R_874_10613@ire(&#39;fs&#39;);//引入文件读取模块 fs.readFile(&#39;./README.md&#39;,(err,data)=&gt
后端代码 在后端的文件 routes文件夹下的connect.js文件中 // 引入mysql const mysql = @R_874_10613@ire(&#39;mysql&#39;); // 创建连接对象 co
path 中方法使用及 __dirname 和 __filename 一、__dirname 和 __filename 1. 概念 1. __dirname 可以用来动态获取当前文件所属目录的绝对路径
express包含的内容:1)主体2)cookie,session3)数据4)模板引擎5)路由需要用到的插件:express---web框架express-static------解析静态资源cookie-parser-------解析cookie,服务端读取客户端设置的cookiecookie-session------解析sessionbody-pa...
@L_675_121@
Node.js学习课程的安排Node.js最大的特点就是:非阻塞IO和事件驱动、模块化驱动  Node的基础概念1)node命令的基本用法(1)进入REPL环境:node,进入REPL环境  .exit     在REPL环境,可以测试Node的一些代码和模块进入window的PowersHell环境:cmd  执行:powersHell     通过命令行执行...
@H_618_1222@
@H_618_1222@
@H_618_1222@ @H_618_1222@
@H_607_15@@H_607_15@
@H_607_15@
@H_607_15@
@H_607_15@
@H_607_15@

大佬总结

以上是大佬教程为你收集整理的node.js使用cheerio制作网络爬虫全部内容,希望文章能够帮你解决node.js使用cheerio制作网络爬虫所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
猜你在找的Node.js相关文章