Nodejs爬妹子图,本人费尽周折试了好多种方式,最后找到了一个好用的nodejs爬妹子图的方法,此代码仅供学习使用。
废话不多说,思路,我们要爬妹子图,首先要找到一个有妹子图的网页,然后从网页中获取这些图片的地址,然后批量下载自己的电脑里,带着这样的思路
需要以下工具
var fs = require('fs');
var path = require('path');
var request = require('request');
var cheerio = require('cheerio');
首先,fs和path模块均为nodejs自带,主要是下面两个,一个是request模块和cheerio模块。
request模块的介绍以及API:https://github.com/request/request
cheerio模块的介绍以及API:https://github.com/cheeriojs/cheerio
简单来说,request模块是用来请求网页的,cheerio是对请求来的网页进行解析的,也就是从html中解析出来图片的src地址
说一下为什么没用jquery解析呢,因为在试验过程中我用npm下载jquery模块之后,引入到文件的时候竟然报错了,详细原因不得而知,然后在网上看到了这个叫cheerio的利器,它跟jquery有很多相似的地方。
安装上面的两个模块
npm install request
npm install cheerio
先找到一个测试页面,比如 http://jandan.net/ooxx/page-1319
我们先要用request来获取这个页面的html
1
2
3
4
5
6
7
8
9
|
var
request
=
require
(
'request'
)
;
var
requrl
=
'http://jandan.net/ooxx/page-1319'
;
request
(
requrl
,
function
(
error
,
response
,
body
)
{
if
(
!
error
&&
response
.
statusCode
==
200
)
{
console
.
log
(
body
)
;
//返回请求页面的HTML
}
}
)
|
运行后会得到大概下面这样的代码
这个就是我们用request请求到的此页面的HTML,然后我们该使用cheerio模块来解析这个页面了
通过审查页面元素我们可以看出,这些妹子图都是放在 class="text" 下的 img 标签中
其实使用cheerio跟jquery是一样的,我们写了一个acquire方法来解析页面中的img标签中的src地址,代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
var
request
=
require
(
'request'
)
;
//引入request
var
cheerio
=
require
(
'cheerio'
)
;
//引入cheerio
var
requrl
=
'http://jandan.net/ooxx/page-1319'
;
request
(
requrl
,
function
(
error
,
response
,
body
)
{
if
(
!
error
&&
response
.
statusCode
==
200
)
{
console
.
log
(
body
)
;
//返回请求页面的HTML
acquireData
(
body
)
;
}
}
)
function
acquireData
(
data
)
{
var
$
=
cheerio
.
load
(
data
)
;
//cheerio解析data
var
meizi
=
$
(
'.text img'
)
.
toArray
(
)
;
//将所有的img放到一个数组中
console
.
log
(
meizi
.
length
)
;
var
len
=
meizi
.
length
;
for
(
var
i
=
0
;
i
<
len
;
i
++
)
{
var
imgsrc
=
meizi
[
i
]
.
attribs
.
src
;
//用循环读出数组中每个src地址
console
.
log
(
imgsrc
)
;
//输出地址
}
}
|
当然,如果你拿不准选择器的话,可以多用console.log来输出,看看取到的地址是否正确,代码运行效果如下
可以看到我们拿到了此页面中所有妹子图的地址,最后一步就是下载这些妹子图了,你不能是一个一个复制这些地址,然后粘贴到浏览器中右键另存为吧,首先,我们要先解析这些图片的文件名,解析文件名很简单,调用path模块中的basename方法就可以得到URL中的文件名
1
2
3
4
5
6
7
8
|
//NodeJs API http://nodejs.org/api/path.html#path_path_basename_p_ext
path
.
basename
(
'http://hehe.com/foo/bar/baz/asdf/quux.jpg'
)
// 返回
'quux.jpg'
|
现在我们有了图片的地址和图片的名字,就可以下载了,在这里我们调用的是request模块的head方法来下载,请求到图片再调用fs文件系统模块中的createWriteStream来下载到本地目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
var
request
=
require
(
'request'
)
;
var
cheerio
=
require
(
'cheerio'
)
;
var
path
=
require
(
'path'
)
;
var
fs
=
require
(
'fs'
)
;
var
requrl
=
'http://jandan.net/ooxx/page-1319'
;
request
(
requrl
,
function
(
error
,
response
,
body
)
{
if
(
!
error
&&
response
.
statusCode
==
200
)
{
console
.
log
(
body
)
;
//返回请求页面的HTML
acquireData
(
body
)
;
}
}
)
function
acquireData
(
data
)
{
var
$
=
cheerio
.
load
(
data
)
;
var
meizi
=
$
(
'.text img'
)
.
toArray
(
)
;
console
.
log
(
meizi
.
length
)
;
var
len
=
meizi
.
length
;
for
(
var
i
=
0
;
i
<
len
;
i
++
)
{
var
imgsrc
=
meizi
[
i
]
.
attribs
.
src
;
console
.
log
(
imgsrc
)
;
var
filename
=
parseUrlForFileName
(
imgsrc
)
;
//生成文件名
downloadImg
(
imgsrc
,
filename
,
function
(
)
{
console
.
log
(
filename
+
' done'
)
;
}
)
;
}
}
function
parseUrlForFileName
(
address
)
{
var
filename
=
path
.
basename
(
address
)
;
return
filename
;
}
var
downloadImg
=
function
(
uri
,
filename
,
callback
)
{
request
.
head
(
uri
,
function
(
err
,
res
,
body
)
{
// console.log('content-type:', res.headers['content-type']); //这里返回图片的类型
// console.log('content-length:', res.headers['content-length']); //图片大小
if
(
err
)
{
console
.
log
(
'err: '
+
err
)
;
return
false
;
}
console
.
log
(
'res: '
+
res
)
;
request
(
uri
)
.
pipe
(
fs
.
createWriteStream
(
'images/'
+
filename
)
)
.
on
(
'close'
,
callback
)
;
//调用request的管道来下载到 images文件夹下
}
)
;
}
;
|
执行之后就可以看到images文件夹下有一大波妹子图了,想要爬多页的话,写个循环就好
注意:有的网站是有反爬机制的,并不是每个网站都可以爬的