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(); 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
加点文字说明,会更好
收到 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();//结束请求,必须,否则会一直请求 好像这些爬虫工具都差不多,都是无法解析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();
})(); 下面这个网站很有意思,什么右键审查元素啊检查啊直接按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();//结束请求,必须,否则会一直请求 反反爬练习题一、
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-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-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();//结束请求,必须,否则会一直请求 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>
*/ 这都是node js实现的爬虫吗?不是py? tg123 发表于 2020-5-19 12:10
这都是node js实现的爬虫吗?不是py?
当然了,有什么问题? 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]