龙空技术网

nodejs使用Puppeteer实现抓取js生成的页面的web服务

散装码农 266

前言:

此刻我们对“ajax请求包头定义”大体比较关注,大家都想要了解一些“ajax请求包头定义”的相关文章。那么小编同时在网络上网罗了一些对于“ajax请求包头定义””的相关资讯,希望朋友们能喜欢,大家快快来学习一下吧!

Puppeteer 由Chrome官方团队进行维护的 Node 库,它提供了一套高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome,人工能在浏览器里做的大部分事情,

Puppeteer都可以做,像打开标签页,打开百度,输入搜索关键词,点击搜索,点击下一页....等日常操作行为都能模拟

为方便远程抓取js生成的页面数据,采用对外提供web服务,该程序采用之前自定义的NodeJs web框架

抓取模块位于netcrawler.js

实现函数为hookWeb,netcrawler.js的源码如下:

var baseCall=require("../../modes/baseCall");

function hookWeb(ctx,params) {

console.log("params",params);

console.log("获得程序参数:",baseCall.getAppArgv());

var m_ReturnJson={};

if(params.jsfile==undefined || params.jsfile=="")

{

m_ReturnJson.bOK=false;

m_ReturnJson.sMsg="缺少参数jsfile";

return m_ReturnJson;

}

if(params.url==undefined || params.url=="") {

m_ReturnJson.bOK=false;

m_ReturnJson.sMsg="缺少参数url";

return m_ReturnJson;

}

runPuppeteer(ctx, function (ctx, m_ReturnJson) {

console.log("HookWeb返回:", JSON.stringify(m_ReturnJson));

baseCall.ReturnJson(ctx.res, m_ReturnJson);

}, params.jsfile, params.url);

}

function runPuppeteer(ctx,callBack,jsname){

const execFile = require('child_process').execFile;

var jsArray=new Array();

jsArray[0]='crawlerjs/'+jsname+".js";

for(var i=3; i<arguments.length; i++){

jsArray[i-2]=arguments[i];

}

let maxSize=5000*1024;

const child = execFile('node', jsArray,{maxBuffer:maxSize},(error, stdout, stderr) => {

if (error) {

console.log(error);

//throw error;

if(callBack!=null){

var m_ReturnJson={};

m_ReturnJson.bOK=false;

m_ReturnJson.sMsg=error.toString();

callBack(ctx,m_ReturnJson);

}

}

console.log(stdout);

var nPos1=stdout.indexOf("####");

if(nPos1!=-1){

var nPos2=stdout.indexOf("####",nPos1+4);

if(nPos2!=-1){

var m_ReturnJson={};

m_ReturnJson.bOK=true;

try {

var jsonString=stdout.substring(nPos1+4,nPos2);

console.log("jsonString:"+jsonString);

m_ReturnJson.m_ReturnOBJ=JSON.parse(jsonString);

}

catch(err){

m_ReturnJson.bOK=false;

m_ReturnJson.sMsg="解析数据错误:"+err;

}

callBack(ctx,m_ReturnJson);

}

}

});

child.on("exit", () => console.log("exit"));

}

对于hookWeb的访问采用 http://地址/netcrawler/hookWeb.ajax?jsfile=jdlink&url=

其中jsfile表示要执行抓取的js文件,url表示要抓取的地址

调用js抓取页面内容的核心函数

runPuppeteer,通过调用execFile唤起node执行指定的js,通过回调函数获得node执行js的返回结果,使用stdout回调函数参数获得执行js的console输出,为便于解析输出

串,定义串包头和包尾,包头和包尾都采用四个#,包头包尾中间包含返回数据的json串

以上面获得京东联盟推广短链接获得商品信息js为例

jdlink文件源码如下

const puppeteer = require('puppeteer');

const devices = require('puppeteer/DeviceDescriptors');

const iPhone = devices['iPhone 6'];//设置设备

//返回数据函数

function returnCrawler(result){

console.log("####"+JSON.stringify(result)+"####");

}

(async () => {

const browser = await puppeteer.launch({

executablePath: '../chrome-win/chrome.exe',//指定chrome

args: [

'–disable-gpu',

'--disable-images', // 允许跨域

],

headless: true//不显示界面

});

console.log(process.argv);

const page = await browser.newPage();

await page.emulate(iPhone);

await page.goto(process.argv[2], {

waitUntil: 'networkidle2' // 等待网络状态为空闲的时候才继续执行

});

try {

await page.addScriptTag({

url: ';

});

}

catch(er)

{

console.log("错误:",er);

}

//页面加载完毕获得页面数据

const result = await page.evaluate(() => {

console.log("加载完毕");

var m_ReturnOBJ={};

try {

if($('#firstImg').length==0)

{

var imgs=$('.waresMain').find('img');

m_ReturnOBJ.pic=imgs[0].src;

m_ReturnOBJ.pname=$('.waresMain').find('.waresRight').find('.name').text();

m_ReturnOBJ.zkmoney=$('.waresMain').find('.waresRight').find('.price').find('.num').text();

m_ReturnOBJ.money=$('.waresMain').find('.waresRight').find('.linePrice').text().replace('¥','');

}

else

{

var imgs=$('#firstImg');

m_ReturnOBJ.pic=imgs[0].src;

m_ReturnOBJ.money= $('#priceSale').text().replace('¥','');

m_ReturnOBJ.pname=$('#itemName').text();

}

}catch(err)

{

m_ReturnOBJ.pic=err;

console.log("错误:"+err);

}

return m_ReturnOBJ;//返回数据

});

returnCrawler(result);

browser.close();

})();

具体puppeteer的使用可参考相关API文档

抓取以上站点的输出日志如下

标签: #ajax请求包头定义