鱼C论坛

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

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

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

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

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

x
刚刚接触nodejs  照着教程做了2个实例,一个是下载图标文件 ,一个是获取网站源码(这里我碰到了著名的乱码问题,好长时间才解决掉)
  1. const https=require("https");
  2. const fs=require("fs");
  3. //下载小甲鱼的网页title图标
  4. url="https://fishc.com.cn/favicon.ico";
  5. req=https.request(url,res=>{
  6.     var arr=[];
  7.     res.on('data', buffer => {
  8.         arr.push(buffer);
  9.     });
  10.         
  11.     res.on('end', () => {
  12.   
  13.         let b=Buffer.concat(arr);
  14.         fs.writeFile("my.ico",b,()=>{
  15.             console.log("下载成功");
  16.         });
  17.     });
  18. });
  19. req.end();
  20. //打印小甲鱼签到页面源码
  21. url2="https://fishc.com.cn/plugin.php?id=k_misign:sign";
  22. req=https.request(  
  23.         url2
  24.     ,res=>{
  25.         var strs=[];
  26.         res.on('data', buffer => {
  27.         strs.push(buffer);
  28.     });
  29.         
  30.     res.on('end', () => {
  31.         //let charset = res.headers['content-type'].match(/(?:charset=)(\w+)/)[1] || 'utf8';
  32.         let buff = Buffer.concat(strs);
  33.         let iconv = require('iconv-lite');//nodejs安装模块npm install ...
  34.         console.log(iconv.decode(buff,"gbk"));
  35.     });
  36. });
  37. req.end();
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-3-15 13:44:38 | 显示全部楼层
  1. const https=require("https");
  2. const fs=require("fs");
  3. //打印小甲鱼抢沙发页面主题正文
  4. url2="https://fishc.com.cn/forum.php?mod=guide&view=sofa";
  5. req=https.request(  
  6.         url2
  7.     ,res=>{
  8.         var strs=[];
  9.         res.on('data', buffer => {
  10.         strs.push(buffer);
  11.     });
  12.       
  13.     res.on('end', () => {
  14.         var cheerio = require('cheerio');
  15.         let buff = Buffer.concat(strs);
  16.         let iconv = require('iconv-lite');//nodejs安装模块npm install ...
  17.         html=iconv.decode(buff,"gbk");
  18.         $ = cheerio.load(html);
  19.         parentitem=$(".bm_c").find("table").find("tbody");
  20.         for(var x =0;x<parentitem.length;x++){
  21.             bm_c=$(parentitem).eq(x).find("th").find("a").text();
  22.             console.log(bm_c);
  23.         }   
  24.      });
  25. });
  26. 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 | 显示全部楼层
  1. const http=require("http");
  2. //打印中国继续医学教育网所有学科名称
  3. surl="http://www.ncme.org.cn/ProjectList.do";
  4. req=http.request(surl,
  5.     res=>{
  6.             var strs=[];
  7.             res.on('data', buffer => {//请求到的数据都在这里了
  8.                 strs.push(buffer);
  9.             });
  10.       
  11.             res.on('end', () => {  //end 请求完成,对数据进行处理的过程
  12.                 var cheerio = require('cheerio');   //高仿jquery对dom进行解析的模块
  13.                 let buff = Buffer.concat(strs);     //对请求回来的数据进行Buffer封装,这里的结果是二进制
  14.                 let iconv = require('iconv-lite');  //  转码模块。。。nodejs安装模块npm install ...
  15.                 html=iconv.decode(buff,"utf8");     // 转码,把二进制转成我们能读懂的string
  16.                 $ = cheerio.load(html);     //导入文本,以便解析器能够解析
  17.                 paritem=$("li[class='so_many item_list']").find("span");   //以下是解析过程,不多说
  18.                 for(var x =0;x<paritem.length;x++){
  19.                     bm_c=$(paritem).eq(x).text();
  20.                     console.log(bm_c);
  21.                 }   
  22.                
  23.             });
  24.             //这里好像还应该有个res.on("error"()=>{});
  25. });
  26. req.end();  //结束请求,必须,否则会一直请求
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-16 09:01:44 | 显示全部楼层
好像这些爬虫工具都差不多,都是无法解析js代码段,碰到一些事情 ,只好依赖无头浏览器
但是这些无头浏览器实在是太慢了,这里仅仅上几行代码,了解一下,不准备深入学习

  1. const puppeteer =require('puppeteer');//引入puppeteer库 主要用途:无头浏览器
  2. (async() => {
  3.         const browser = await puppeteer.launch({headless: false,timeout: 30000});//用指定选项启动一个Chromium浏览器实例。
  4.         const page = await browser.newPage();    //创建一个页面.
  5.         await page.goto('https://fishc.com.cn/forum.php');  //到指定页面的网址
  6.         //await page.screenshot({path:'example.png'});//截图并保存到当前路径,名称为example.png.
  7.         //await browser.close();                      //关闭已打开的页面,browser不能再使用。
  8.         //console.log(await page.content());
  9.         //await page.waitForNavigation();
  10.         //登录
  11.         await page.type('#ls_username',"wp231957");
  12.         await page.type('#ls_password',"密码");
  13.         await page.click("button[class='pn vm']");
  14.         //页面登录成功后,需要保证redirect 跳转到请求的页面
  15.         //await page.waitForNavigation();
  16. })();
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

  4. //构造参数
  5. var xueke="儿科护理学";
  6. var post_data=querystr.stringify({
  7.     "search_input":"",
  8.     "xueke":xueke,
  9.     "brand":"",
  10.     "mode":"",
  11.     "pid":xueke,
  12.     "sign":"",
  13.     "level_h":"-1",
  14.     "forma":"",
  15.     "score_sort":"",
  16.     "cost_sort":""

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

  45. req.end();  //结束请求,必须,否则会一直请求
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-16 18:46:02 | 显示全部楼层
反反爬练习题一、

  1. const http=require("http");
  2. //const fs=require("fs");
  3. //反反爬练习题一   
  4. url2="http://www.porters.vip/verify/uas/index.html";
  5. req=http.request(url2
  6.     ,res=>{
  7.             var strs=[];
  8.             res.on('data', buffer => {
  9.                 strs.push(buffer);
  10.             });
  11.       
  12.             res.on('end', () => {
  13.                 var cheerio = require('cheerio');
  14.                 let buff = Buffer.concat(strs);
  15.                 let iconv = require('iconv-lite');
  16.                 html=iconv.decode(buff,"utf8");
  17.                 console.log(html);
  18.                   
  19.             });
  20. });
  21. req.end();
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-16 18:49:46 | 显示全部楼层
本帖最后由 wp231957 于 2020-3-17 16:02 编辑

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

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

  4. // 构建options
  5. var options={
  6.     hostname:"www.porters.vip",
  7.     port:80,
  8.     //这是一个重定向的路由
  9.     //重定向后是headers里的 "Referer"
  10.     //但是,如果你去请求"Referer"链,你会失望的
  11.     path:"/verify/cookie/content.html",
  12.     method:"GET",
  13.     //这个headers中 也不知道哪些是必须的,反正把F12中所有的都搬过来
  14.     //肯定是不行的,这些估计也有非必须的,懒得测试了
  15.     headers:{
  16.         "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
  17.         "Accept-Language": "zh-CN,zh;q=0.9",
  18.         "Connection": "keep-alive",
  19.         "Cookie": "isfirst=789kq7uc1pp4c",
  20.         "Host": "www.porters.vip",
  21.         "Referer": "http://www.porters.vip/verify/cookie/index.html",
  22.         "Upgrade-Insecure-Requests": "1",
  23.         "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3947.100 Safari/537.36"
  24.     }
  25. };
  26. req=http.request(options,
  27.     res=>{
  28.         var str="";
  29.         res.on('data', buffer => {
  30.             str+=buffer;
  31.         });
  32.    
  33.         res.on('end', () => {
  34.             console.log(str);
  35.               
  36.         });
  37.            
  38. });
  39. req.on('error', function (e) {
  40.     console.log('problem with request: ' + e.message);
  41. });

  42. req.end();  //结束请求,必须,否则会一直请求
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-16 18:53:06 | 显示全部楼层
本帖最后由 wp231957 于 2020-3-17 11:08 编辑

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

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

  34. req.end();  //结束请求,必须,否则会一直请求
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-21 19:08:51 | 显示全部楼层
  1. const sync=require("sync-request");   //负责同步的,本例申请两个请求,用异步实在是不知道咋处理
  2. var cheerio = require('cheerio');     //负责调用伪jquery语法的  本代码中没用到,多余的
  3. let iconv = require('iconv-lite');    //负责转码的
  4. //反反爬练习题六
  5. //取映射键串及对应的偏移,以便转译出真身
  6. url1="http://www.porters.vip/confusion/css/food.css";
  7. var arr1=new Array();    //存放css里面的映射后的数据
  8. var resp1=sync("GET",url1);
  9. html1=iconv.decode(resp1.body,"utf8");
  10. var reg1=/vhk[a-z0-9]{3}\s+{\s+\w+:\s+\-\d+px\s+\-\d+px;\s+}/gm;
  11. txt=html1.match(reg1);
  12. for(var x=0;x<txt.length;x++){
  13.     var r1=txt[x].replace(/background:|px|;/g,"").replace(/{|}|\n|\-/g,"");
  14.     arr1.push(r1);
  15. }

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

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

  34. }

  35. //再转json
  36. var arr4=new Array();  //存放CSS里的映射数据转成json后的数据
  37. for(var x=0;x<arr1.length;x++){
  38.     var s=arr1[x].split(/\s+/);
  39.    
  40.     var key=s[0];
  41.     var value=s[1]+","+s[2];
  42.     var tmp="{"+'"'+key+'"'+":"+'"'+value+'"'+"}";
  43.     arr4.push(JSON.parse(tmp));

  44. }
  45. //取真身
  46. function getstring(idx,num){
  47.     for(var x=0;x<arr3.length;x++){
  48.         for (var key in arr3[x]){
  49.             if(num<parseInt(key)){   //取行数
  50.                 return arr3[x][key][parseInt(idx/14)];  //取列数
  51.              }
  52.         }
  53.       
  54.     }
  55. }
  56. //打印映射关系
  57. for(var x=0;x<arr4.length;x++){
  58.     for (var key in arr4[x]){
  59.         value=arr4[x][key].split(",");
  60.         console.log(key,"=",getstring(parseInt(value[0]),parseInt(value[1])));
  61.     };
  62. };

  63. /*
  64. PS E:\wp> node app10
  65. vhk08k = 0
  66. vhk6zl = 1
  67. vhk0ao = 1
  68. vhk9or = 2
  69. vhkfln = 3
  70. vhkbvu = 4
  71. vhk84t = 5
  72. vhkvxd = 6
  73. vhkqsc = 7
  74. vhkjj4 = 8
  75. vhk0f1 = 9
  76. PS E:\wp>
  77. */
复制代码
想知道小甲鱼最近在做啥?请访问 -> 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
当然了,有什么问题?
  1. var sync = require("sync-request"); //同步


  2. var url = 'https://www.toutiao.com/api/pc/feed/?';
  3. var headers = {
  4.     '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'
  5. };
  6. var params = {
  7.     'min_behot_time': '0',
  8.     'refresh_count': '1',
  9.     'category': 'news_tech',
  10.     'utm_source': 'toutiao',
  11.     'widen': '1',
  12.     'tadrequire': 'true',
  13.     '_signature': '_02B4Z6wo00d01eDWtRwAAIDCJl-taOBJ2t3g8rGAABjn6cxBkgtLHOzFJDtYU3VcM3cwz7YTApRXybmmU.YUUyEYXOEM4BNeozIGE.z4PkW17XPWjlbWGm5GC315aHiR6t3KAXnWcmprpg2.f1'
  14. };
  15. var resp = sync("GET", url);
  16. var res = JSON.parse(resp.body);
  17. console.log(res);
复制代码


这个params 没有用到  也检测到了数据,初步怀疑  大概率 这个params 就是糊弄人的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-27 22:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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