当前位置: 首页 > 工具软件 > Cool-Node > 使用案例 >

node 爬虫 请求数据 保存到文件夹 (node 响应数据) -node 请求库

颜乐
2023-12-01

参考:https://www.cnblogs.com/goloving/p/13494617.html

axios请求库


// https://ysch-user.oss-cn-shenzhen.aliyuncs.com/ XML

const axios = require("axios");
const Qs = require("qs"); //qs是一个url参数转化(parse/stringify)的js库
async function testPOST() {
let response = await axios({
method: "get",
url: "https://ysch-user.oss-cn-shenzhen.aliyuncs.com/",
});
console.log(response);
}
testPOST();

// post 请求内容
// const axios = require("axios");
// const Qs = require("qs");  //qs是一个url参数转化(parse/stringify)的js库

// async function testPOST() {
// let response = await axios({
// method: "POST",
// headers: { "Content-Type": "application/x-www-form-urlencoded" },
// url: url,
// data: Qs.stringify(param)
// })
// console.log(response)
// }


// 请求get
// const axios = require("axios");
// const path = require("path");
// const fs = require("fs");
// const filePath = "E:\\testAPI" //希望把文件下载到哪里

 
// async function testGET(){
//   if (!fs.existsSync(filePath)) {
//     fs.mkdirSync(filepath)
//   }
//   /* name是生成的文件的文件名,自定义,比如,我希望产生的文件名为test.pdf,那么name='test.pdf' */
//   const mypath = path.resolve(filePath, name)
//  const writer = fs.createWriteStream(mypath)
//  let response = await axios({
//   url: resource, //需要访问的资源链接
//   method: "GET",
//   responseType: "stream",
//   params: param //需要传的参数
//   })
//  response.data.pipe(writer)
//  return new Promise((resolve, reject) => {
//   writer.on("finish", resolve)
//   writer.on("error", reject)
//  })
// } 

http请求

//加载http模块
var http = require("http");
const fs = require("fs");

//目标网站,嘿嘿,这个网站有很多实习职位
var pageUrl =
  "http://geo.datav.aliyun.com/areas_v3/bound/geojson?code=440300_full";
  http.get(pageUrl, function (res) {
  var html = "";
  res.on("data", function (data) {
    html += data;
  });
   res.on("end", function () {
    fs.writeFile("./map/shenzhen.json", html, function (err) {
      if (err) {
        console.log("写文件操作失败");
      } else {
        console.log("写文件操作成功");
      }
    });
    console.log(html);
  });
});

var province_list = {},
  city_list = {},
  county_list = {};
total.forEach((item, index) => {
  province_list[item.value] = item.label;
  item["children"].forEach((item1, index1) => {
    city_list[item1.value] = item1.label;
    item1["children"].forEach((item2, index2) => {
      county_list[item2.value] = item2.label;
    });
  });
});

let areaList = {
  province_list,
  city_list,
  county_list,
};

// fs.writeFileSync('./message.json',JSON.stringify(areaList));
//加载http模块
var http = require("http");
// const fs = require("fs");

// city_list = {
//   654000: "伊利自治州",
// };

for (let key in city_list) {
  //目标网站,嘿嘿,这个网站有很多实习职位
  var pageUrl =
    "http://geo.datav.aliyun.com/areas_v3/bound/geojson?code=" + key + "_full";

  http.get(pageUrl, function (res) {
    var html = "";
    res.on("data", function (data) {
      html += data;
    });
    res.on("end", function () {
      fs.access("./map", (err) => {
        if (err) {
          // reject(false);//"不存在"
          console.log(err, "没有map 文件夹");
          fs.mkdir("map", function (error) {
            if (error) {
              console.log(error);
              console.log("创建目录失败");
              return false;
            } else {
              console.log(err, "成功");
              fs.writeFile(`./map/${key}.json`, html, function (err) {
                if (err) {
                  console.log("写文件操作失败");
                } else {
                  console.log("写文件操作成功");
                }
              });
              console.log("创建目录成功");
            }
          });
        } else {
          // resolve(true);//"存在"
          console.log(err, "有map文件夹");
          fs.writeFile(`./map/${key}.json`, html, function (err) {
            if (err) {
              console.log("写文件操作失败");
            } else {
              console.log("写文件操作成功");
            }
          });
        }
      });

      // console.log(html);
    });
  });
}

发现node可以爬虫,正好我在找暑期实习,然后就使用node爬一下网站数据找实习。

准备工作
安装node,npm安装依赖包[cheerio, express, eventproxy]
http和express模块的使用学习
爬取目标网站

//加载http模块
var http = require('http');

//目标网站,嘿嘿,这个网站有很多实习职位
var pageUrl = 'http://shixi.info/';

http.get(pageUrl, function(res) {
    var html = '';
    res.on('data', function(data) {
        html += data;
    });
    res.on('end', function() {
        console.log(html);
    });
});

转载:https://www.cnblogs.com/Aralic/p/4591036.html
http的get请求一个目标网站,回调函数的参数是response,绑定两个事件,一个’data’事件,会不断触发获取数据,数据获取完触发’end‘ 事件。

爬到的的数据就是目标网站的html源代码。

现在html代码有了,我们该怎么解析这个呢?

解析html代码
在这里我们使用cheerio模块,是服务器端的html解析模块,使用方法类型jQuery

var http = require('http');
var cheerio = require('cheerio');
var pageUrl = 'http://shixi.info/';

http.get(pageUrl, function(res) {
    var html = '';
    res.on('data', function(data) {
        html += data;
    });
    res.on('end', function() {
        //数据获取完,执行回调函数
        callback(html);
    });
});

function callback(html) {
    //使用load方法,参数是刚才获取的html源代码数据
    var $ = cheerio.load(html);
    var arrUrl = [];
    
    //写法和jQuery一模一样,有没有觉得很cool
    $('article').each(function(index, element) {
        var href = $(element).find('.entry-title a').attr('href');
        arrUrl.push(href);
    });
}

这样我们就把目标页面的每条招聘信息的网址存放进了一个数组,当然我们也可以通过对象字面量存一些其他数据,比如招聘信息的title,date等等。

可能有人会问,我只要网址干嘛?嘿嘿,因为JD是在详情页里面,不去爬详情页,我咋看JD。

并发请求
为演示方便:只获取了职位title。

对arrUrl迭代,GET请求。因为是异步操作,所以在这里我们建一个count变量,每次完成一个操作count++,执行done函数,如果count值和arrUrl数组的长度相同,执行函数。

var count = 0;
var results = [];
function done() {
    if (count == arrUrl.length) {
        console.log('done');
    }
}
arrUrl.forEach(function(item, index) {
    http.get(item, function(res) {
        var html = '';
        res.on('data', function(data) {
            html += data;
        });

        res.on('end', function() {
            var $ = cheerio.load(html);
            var title = $('.entry-title').text();

            results[index] = {
                url: item,
                title: title
            };
            count++;
            done();
        }); 
    });
});

使用express模块让数据响应到网页

var express = require('express');
var app = express();

function done() {
    if (count == arrUrl.length) {
        //get 方法,第一个参数路径,是一个route的作用。
        //回调函数,参数分别是:请求,响应。
        //监听8888端口,浏览器打开 http://127.0.0.1:8888
        app.get('/', function(req, res) {
            res.send(JSON.stringify(results));
        }).listen('8888', '127.0.0.1');
        console.log('done');
    }
}

浏览器打开 http://127.0.0.1:8888,就能看到我们爬的数据了。

当然我们也可以 对这些数据处理一下,返回到网页的是html内容文本。

使用eventproxy模块控制并发
刚才我们使用的是count变量,有些不够优雅。这里我们引入eventproxy模块。

var eventproxy = require('eventproxy');
//得到实例化对象ep
var ep = new eventproxy();

//after,第一个参数是事件名,第二个参数是事件的数量,回调函数的参数是list集合,
ep.after('subscribe', arrUrl.length, function(results) {
    app.get('/', function(req, res) {
        res.send(JSON.stringify(results));
    }).listen('8888', '127.0.0.1');
    console.log('done');
});

arrUrl.forEach(function(item, index) {
    http.get(item, function(res) {
        var html = '';
        res.on('data', function(data) {
            html += data;
        });

        res.on('end', function() {
            var $ = cheerio.load(html);
            var title = $('.entry-title').text();
            
            //通知ep的subscribe事件,ep监测执行完的事件数量等于arrUrl.length,如果等于 执行回到函数。
            ep.emit('subscribe', {
                url: item,
                title: title
            });

        }); 
  });
 类似资料: