wp231957 发表于 2020-3-15 10:06:20

NODEJS爬虫系列基础

刚刚接触nodejs照着教程做了2个实例,一个是下载图标文件 ,一个是获取网站源码(这里我碰到了著名的乱码问题,好长时间才解决掉)
const https=require("https");
const fs=require("fs");
//下载小甲鱼的网页title图标
url="https://fishc.com.cn/favicon.ico";
req=https.request(url,res=>{
    var arr=[];
    res.on('data', buffer => {
      arr.push(buffer);
    });
      
    res.on('end', () => {

      let b=Buffer.concat(arr);
      fs.writeFile("my.ico",b,()=>{
            console.log("下载成功");
      });
    });
});
req.end();
//打印小甲鱼签到页面源码
url2="https://fishc.com.cn/plugin.php?id=k_misign:sign";
req=https.request(
      url2
    ,res=>{
      var strs=[];
      res.on('data', buffer => {
      strs.push(buffer);
    });
      
    res.on('end', () => {
      //let charset = res.headers['content-type'].match(/(?:charset=)(\w+)/) || 'utf8';
      let buff = Buffer.concat(strs);
      let iconv = require('iconv-lite');//nodejs安装模块npm install ...
      console.log(iconv.decode(buff,"gbk"));
    });
});
req.end();

wp231957 发表于 2020-3-15 13:44:38

const https=require("https");
const fs=require("fs");
//打印小甲鱼抢沙发页面主题正文
url2="https://fishc.com.cn/forum.php?mod=guide&view=sofa";
req=https.request(
      url2
    ,res=>{
      var strs=[];
      res.on('data', buffer => {
      strs.push(buffer);
    });
      
    res.on('end', () => {
      var cheerio = require('cheerio');
      let buff = Buffer.concat(strs);
      let iconv = require('iconv-lite');//nodejs安装模块npm install ...
      html=iconv.decode(buff,"gbk");
      $ = cheerio.load(html);
      parentitem=$(".bm_c").find("table").find("tbody");
      for(var x =0;x<parentitem.length;x++){
            bm_c=$(parentitem).eq(x).find("th").find("a").text();
            console.log(bm_c);
      }   
   });
});
req.end();

不二如是 发表于 2020-3-15 17:56:31

加点文字说明,会更好

wp231957 发表于 2020-3-15 18:05:25

不二如是 发表于 2020-3-15 17:56
加点文字说明,会更好

收到

wp231957 发表于 2020-3-16 08:57:39

const http=require("http");
//打印中国继续医学教育网所有学科名称
surl="http://www.ncme.org.cn/ProjectList.do";
req=http.request(surl,
    res=>{
            var strs=[];
            res.on('data', buffer => {//请求到的数据都在这里了
                strs.push(buffer);
            });
      
            res.on('end', () => {//end 请求完成,对数据进行处理的过程
                var cheerio = require('cheerio');   //高仿jquery对dom进行解析的模块
                let buff = Buffer.concat(strs);   //对请求回来的数据进行Buffer封装,这里的结果是二进制
                let iconv = require('iconv-lite');//转码模块。。。nodejs安装模块npm install ...
                html=iconv.decode(buff,"utf8");   // 转码,把二进制转成我们能读懂的string
                $ = cheerio.load(html);   //导入文本,以便解析器能够解析
                paritem=$("li").find("span");   //以下是解析过程,不多说
                for(var x =0;x<paritem.length;x++){
                  bm_c=$(paritem).eq(x).text();
                  console.log(bm_c);
                }   
               
            });
            //这里好像还应该有个res.on("error"()=>{});
});
req.end();//结束请求,必须,否则会一直请求

wp231957 发表于 2020-3-16 09:01:44

好像这些爬虫工具都差不多,都是无法解析js代码段,碰到一些事情 ,只好依赖无头浏览器
但是这些无头浏览器实在是太慢了,这里仅仅上几行代码,了解一下,不准备深入学习

const puppeteer =require('puppeteer');//引入puppeteer库 主要用途:无头浏览器
(async() => {
      const browser = await puppeteer.launch({headless: false,timeout: 30000});//用指定选项启动一个Chromium浏览器实例。
      const page = await browser.newPage();    //创建一个页面.
      await page.goto('https://fishc.com.cn/forum.php');//到指定页面的网址
      //await page.screenshot({path:'example.png'});//截图并保存到当前路径,名称为example.png.
      //await browser.close();                      //关闭已打开的页面,browser不能再使用。
      //console.log(await page.content());
      //await page.waitForNavigation();
      //登录
      await page.type('#ls_username',"wp231957");
      await page.type('#ls_password',"密码");
      await page.click("button");
      //页面登录成功后,需要保证redirect 跳转到请求的页面
      //await page.waitForNavigation();
})();

wp231957 发表于 2020-3-16 11:15:22

下面这个网站很有意思,什么右键审查元素啊检查啊直接按F12啊都给你转走了转到它自己的开发者工具上(当然了,这个工具你啥也干不了):
典型的 浏览器地址栏地址不变,内部页面变动,大概就是AJAX吧   ,不咋会用FIDDLER没分析太明白,不过数据还是拿到了
下面源码 NODE.JS+POST 参数

const http=require("http");
const querystr=require("querystring");
//探索医学继续教育网学科部分(没有HREF,是用post请求参数方式)

//构造参数
var xueke="儿科护理学";
var post_data=querystr.stringify({
    "search_input":"",
    "xueke":xueke,
    "brand":"",
    "mode":"",
    "pid":xueke,
    "sign":"",
    "level_h":"-1",
    "forma":"",
    "score_sort":"",
    "cost_sort":""

});
var contentLen = Buffer.byteLength(post_data, 'utf8');   //很重要很重要
// 构建options
var options={
    hostname:"www.ncme.org.cn",
    port:80,
    path:"/ProjectList.do",
    method:"POST",   
    headers: {'Content-Type': 'application/x-www-form-urlencoded','Content-Length': contentLen}   //很重要很重要
};
req=http.request(options,
    res=>{
            var strs=[];
            res.on('data', buffer => {//请求到的数据都在这里了
                strs.push(buffer);
            });
      
            res.on('end', () => {//end 请求完成,对数据进行处理的过程
            
                let buff = Buffer.concat(strs);   //对请求回来的数据进行Buffer封装,这里的结果是二进制
                let iconv = require('iconv-lite');//转码模块。。。nodejs安装模块npm install ...
                html=iconv.decode(buff,"utf8");   // 转码,把二进制转成我们能读懂的string
                console.log(html);
                     
            });
            //这里好像还应该有个res.on("error"()=>{});
});
req.write(post_data);//发送内容

req.end();//结束请求,必须,否则会一直请求

wp231957 发表于 2020-3-16 18:46:02

反反爬练习题一、

const http=require("http");
//const fs=require("fs");
//反反爬练习题一   
url2="http://www.porters.vip/verify/uas/index.html";
req=http.request(url2
    ,res=>{
            var strs=[];
            res.on('data', buffer => {
                strs.push(buffer);
            });
      
            res.on('end', () => {
                var cheerio = require('cheerio');
                let buff = Buffer.concat(strs);
                let iconv = require('iconv-lite');
                html=iconv.decode(buff,"utf8");
                console.log(html);
                  
            });
});
req.end();

wp231957 发表于 2020-3-16 18:49:46

本帖最后由 wp231957 于 2020-3-17 16:02 编辑

反反爬题目二
题目说是主要考察cookie 实际上 也不知道都用了啥反扒措施,反正总是给我抛出302

const http=require("http");
//反反爬练习题二
//"http://www.porters.vip/verify/cookie/content.html"

// 构建options
var options={
    hostname:"www.porters.vip",
    port:80,
    //这是一个重定向的路由
    //重定向后是headers里的 "Referer"
    //但是,如果你去请求"Referer"链,你会失望的
    path:"/verify/cookie/content.html",
    method:"GET",
    //这个headers中 也不知道哪些是必须的,反正把F12中所有的都搬过来
    //肯定是不行的,这些估计也有非必须的,懒得测试了
    headers:{
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
      "Accept-Language": "zh-CN,zh;q=0.9",
      "Connection": "keep-alive",
      "Cookie": "isfirst=789kq7uc1pp4c",
      "Host": "www.porters.vip",
      "Referer": "http://www.porters.vip/verify/cookie/index.html",
      "Upgrade-Insecure-Requests": "1",
      "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3947.100 Safari/537.36"
    }
};
req=http.request(options,
    res=>{
      var str="";
      res.on('data', buffer => {
            str+=buffer;
      });
   
      res.on('end', () => {
            console.log(str);
            
      });
         
});
req.on('error', function (e) {
    console.log('problem with request: ' + e.message);
});

req.end();//结束请求,必须,否则会一直请求

wp231957 发表于 2020-3-16 18:53:06

本帖最后由 wp231957 于 2020-3-17 11:08 编辑

反反爬题目三、(get发送参数是md5加密的)sign签名验证
const http=require("http");
const querystr=require("querystring");
const md5=require("./md5.js");       //这个是关键的关键    这里的反扒还是给留了后门,虽然我不懂md5算法,但是却可以直接拿过来用
//反反爬练习题三
//url2="http://www.porters.vip/verify/sign/";

// 构建options
var options={
    hostname:"www.porters.vip",
    port:80,
    path:"/verify/sign/fet"+md5.uri(),      //这个get的参数是通过uri这个函数计算出来的到F12控制台里COPY出来的是无效的
    method:"GET",
};
req=http.request(options,
    res=>{
            //console.log(options);
            var strs=[];
            res.on('data', buffer => {//请求到的数据都在这里了
                strs.push(buffer);
            });
      
            res.on('end', () => {//end 请求完成,对数据进行处理的过程
            
                let buff = Buffer.concat(strs);   //对请求回来的数据进行Buffer封装,这里的结果是二进制
                let iconv = require('iconv-lite');//转码模块。。。nodejs安装模块npm install ...
                html=iconv.decode(buff,"utf8");   // 转码,把二进制转成我们能读懂的string
                console.log(html);
                     
            });
         
});
req.on('error', function (e) {
    console.log('problem with request: ' + e.message);
});

req.end();//结束请求,必须,否则会一直请求

wp231957 发表于 2020-3-21 19:08:51

const sync=require("sync-request");   //负责同步的,本例申请两个请求,用异步实在是不知道咋处理
var cheerio = require('cheerio');   //负责调用伪jquery语法的本代码中没用到,多余的
let iconv = require('iconv-lite');    //负责转码的
//反反爬练习题六
//取映射键串及对应的偏移,以便转译出真身
url1="http://www.porters.vip/confusion/css/food.css";
var arr1=new Array();    //存放css里面的映射后的数据
var resp1=sync("GET",url1);
html1=iconv.decode(resp1.body,"utf8");
var reg1=/vhk{3}\s+{\s+\w+:\s+\-\d+px\s+\-\d+px;\s+}/gm;
txt=html1.match(reg1);
for(var x=0;x<txt.length;x++){
    var r1=txt.replace(/background:|px|;/g,"").replace(/{|}|\n|\-/g,"");
    arr1.push(r1);
}

//取svg里面有用的串
url2="http://www.porters.vip/confusion/font/food.svg";
var arr2=new Array();    //存放svg里的有用数据
var resp2=sync("GET",url2);
html2=iconv.decode(resp2.body,"utf8");
var reg2=/y=\"\d+\">\d+/gm;
txt2=html2.match(reg2);
for(var x=0;x<txt2.length;x++){
    var r2=txt2.replace(/>/g," ").replace(/\"|y=/g,"");
    arr2.push(r2);
}

//转个json 好麻烦
var arr3=new Array();   //存放svg里的有用数据转成json后的数据
for(var x=0;x<arr2.length;x++){
    var key=arr2.split(" ");
    var value=arr2.split(" ");
    var tmp="{"+'"'+key+'"'+":"+'"'+value+'"'+"}";
    arr3.push(JSON.parse(tmp));

}

//再转json
var arr4=new Array();//存放CSS里的映射数据转成json后的数据
for(var x=0;x<arr1.length;x++){
    var s=arr1.split(/\s+/);
   
    var key=s;
    var value=s+","+s;
    var tmp="{"+'"'+key+'"'+":"+'"'+value+'"'+"}";
    arr4.push(JSON.parse(tmp));

}
//取真身
function getstring(idx,num){
    for(var x=0;x<arr3.length;x++){
      for (var key in arr3){
            if(num<parseInt(key)){   //取行数
                return arr3;//取列数
             }
      }
      
    }
}
//打印映射关系
for(var x=0;x<arr4.length;x++){
    for (var key in arr4){
      value=arr4.split(",");
      console.log(key,"=",getstring(parseInt(value),parseInt(value)));
    };
};

/*
PS E:\wp> node app10
vhk08k = 0
vhk6zl = 1
vhk0ao = 1
vhk9or = 2
vhkfln = 3
vhkbvu = 4
vhk84t = 5
vhkvxd = 6
vhkqsc = 7
vhkjj4 = 8
vhk0f1 = 9
PS E:\wp>
*/

tg123 发表于 2020-5-19 12:10:53

这都是node js实现的爬虫吗?不是py?

wp231957 发表于 2020-5-19 12:18:31

tg123 发表于 2020-5-19 12:10
这都是node js实现的爬虫吗?不是py?

当然了,有什么问题?

wp231957 发表于 2021-6-22 15:34:33

wp231957 发表于 2020-5-19 12:18
当然了,有什么问题?

var sync = require("sync-request"); //同步


var url = 'https://www.toutiao.com/api/pc/feed/?';
var headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
};
var params = {
    'min_behot_time': '0',
    'refresh_count': '1',
    'category': 'news_tech',
    'utm_source': 'toutiao',
    'widen': '1',
    'tadrequire': 'true',
    '_signature': '_02B4Z6wo00d01eDWtRwAAIDCJl-taOBJ2t3g8rGAABjn6cxBkgtLHOzFJDtYU3VcM3cwz7YTApRXybmmU.YUUyEYXOEM4BNeozIGE.z4PkW17XPWjlbWGm5GC315aHiR6t3KAXnWcmprpg2.f1'
};
var resp = sync("GET", url);
var res = JSON.parse(resp.body);
console.log(res);

这个params 没有用到也检测到了数据,初步怀疑大概率 这个params 就是糊弄人的
页: [1]
查看完整版本: NODEJS爬虫系列基础