鱼C论坛

 找回密码
 立即注册
查看: 4123|回复: 13

[学习笔记] NODEJS爬虫系列基础

[复制链接]
发表于 2020-3-15 10:06:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
刚刚接触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+)/)[1] || 'utf8';
        let buff = Buffer.concat(strs);
        let iconv = require('iconv-lite');//nodejs安装模块npm install ...
        console.log(iconv.decode(buff,"gbk"));
    });
});
req.end();
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 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();
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-15 17:56:31 | 显示全部楼层
加点文字说明,会更好
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-15 18:05:25 From FishC Mobile | 显示全部楼层
不二如是 发表于 2020-3-15 17:56
加点文字说明,会更好

收到
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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[class='so_many item_list']").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();  //结束请求,必须,否则会一直请求
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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[class='pn vm']");
        //页面登录成功后,需要保证redirect 跳转到请求的页面
        //await page.waitForNavigation();
})();
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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();  //结束请求,必须,否则会一直请求
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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();
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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();  //结束请求,必须,否则会一直请求
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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();  //结束请求,必须,否则会一直请求
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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[a-z0-9]{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[x].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[x].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[x].split(" ")[0];
    var value=arr2[x].split(" ")[1];
    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[x].split(/\s+/);
    
    var key=s[0];
    var value=s[1]+","+s[2];
    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[x]){
            if(num<parseInt(key)){   //取行数
                return arr3[x][key][parseInt(idx/14)];  //取列数
             }
        }
       
    }
}
//打印映射关系
for(var x=0;x<arr4.length;x++){
    for (var key in arr4[x]){
        value=arr4[x][key].split(",");
        console.log(key,"=",getstring(parseInt(value[0]),parseInt(value[1])));
    };
};

/*
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>
*/
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-19 12:10:53 | 显示全部楼层
这都是node js实现的爬虫吗?不是py?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-19 12:18:31 From FishC Mobile | 显示全部楼层
tg123 发表于 2020-5-19 12:10
这都是node js实现的爬虫吗?不是py?

当然了,有什么问题?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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 就是糊弄人的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-6-19 21:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表