我的递归函数不是无限循环。为什么?
My recursive function isnt in infinite loop. Why?
噩梦在起作用,当然我正在测试这个工具,但顺便说一下,主要问题是为什么我的函数没有进入无限循环?因为我没有提出页面的条件。我可能做错了吗?
我想要的情况是:每当页面加载时,我都会得到页面的标题,然后再次调用该函数到下一页直到最后一页。
我也尝试了 setTimeout,但没有成功。
我的控制台日志只打印 1 然后完成。
代码片段在这里:-
var pagn = 1;
function ab(page){
nightmare.goto(url_base+"&page="+page)
.evaluate(() => {
return document.title;
})
.end()
.then((title) => {
console.log(title + ":" + page);
ab(++pagn);
//setTimeout("page(" + page + ")", 5000);
}).catch(()=>{console.log("Error");});
}
ab(pagn);
如果 nightmare.goto() 抛出拒绝怎么办。你应该实现 catch()
page++
没有将增量值作为其 post 增量运算符传递。 page + 1
或 ++page
应该可以解决问题。
var page = 1;
function ab(page){
nightmare.goto(url_base+"&page="+page)
.evaluate(() => {
return document.title;
})
.end()
.then((title) => {
console.log(title + ":" + page);
ab(page+1);
//setTimeout("page(" + page + ")", 5000);
}).catch(error => {
console.error('Search failed:', error)
ab(page);
});
}
ab(page);
你不应该在定义全局变量时传递页面变量,否则它每次都会被覆盖..
var page = 1;
function ab(){
nightmare.goto(url_base+"&page="+page)
.evaluate(() => {
return document.title;
})
.end()
.then((title) => {
console.log(title + ":" + page);
ab(page++);
//setTimeout("page(" + page + ")", 5000);
});
}
ab();
问题是您正在使用 .end()
语句结束 nightmare 会话,这会停止噩梦引擎,因此节点会在 运行 之后通过剩余的 [=12] 退出=] 语句。
为了测试你的代码,我稍微重写了你的函数,以便它抓取特定网站,并在多次找到相同页面时退出(这有点像我的测试场景,所以你可能需要调整它对于你的代码)
const Nightmare = require('nightmare')
const nightmare = Nightmare({ show: true })
function scrapePages( targetUrl, curPage = 0, transform = (url, page) => `${url}?page=${page}`, pageSet = new Set() ) {
console.info('Trying to scrape page ' + transform( targetUrl, curPage ) );
return nightmare
.goto( transform( targetUrl, curPage ) )
.evaluate( () => document.title )
.then( (title) => {
if (pageSet.has( title )) {
throw 'page already exists';
}
pageSet.add( title );
console.info( title + ':' + curPage );
return scrapePages( targetUrl, curPage + 1, transform, pageSet );
})
.catch( ( err ) => {
console.error( err );
return { maxPages: curPage, pages: pageSet };
} );
}
scrapePages( 'some-paged-url', 0, (url, page) => url + '/' + (page + 1) )
.then( ({ maxPages, pages }) => {
// end nightmare process
nightmare.end().then( () => {
console.info(`Found ${maxPages} pages`);
});
} )
.catch( err => console.error('Error occured', err ) );
最大的区别,如您所见,噩梦过程的结束仅在抓取 运行 完成后发生。届时,您将拥有可用的总页数和所有调用成功的页数
噩梦在起作用,当然我正在测试这个工具,但顺便说一下,主要问题是为什么我的函数没有进入无限循环?因为我没有提出页面的条件。我可能做错了吗?
我想要的情况是:每当页面加载时,我都会得到页面的标题,然后再次调用该函数到下一页直到最后一页。
我也尝试了 setTimeout,但没有成功。
我的控制台日志只打印 1 然后完成。
代码片段在这里:-
var pagn = 1;
function ab(page){
nightmare.goto(url_base+"&page="+page)
.evaluate(() => {
return document.title;
})
.end()
.then((title) => {
console.log(title + ":" + page);
ab(++pagn);
//setTimeout("page(" + page + ")", 5000);
}).catch(()=>{console.log("Error");});
}
ab(pagn);
如果 nightmare.goto() 抛出拒绝怎么办。你应该实现 catch()
page++
没有将增量值作为其 post 增量运算符传递。 page + 1
或 ++page
应该可以解决问题。
var page = 1;
function ab(page){
nightmare.goto(url_base+"&page="+page)
.evaluate(() => {
return document.title;
})
.end()
.then((title) => {
console.log(title + ":" + page);
ab(page+1);
//setTimeout("page(" + page + ")", 5000);
}).catch(error => {
console.error('Search failed:', error)
ab(page);
});
}
ab(page);
你不应该在定义全局变量时传递页面变量,否则它每次都会被覆盖..
var page = 1;
function ab(){
nightmare.goto(url_base+"&page="+page)
.evaluate(() => {
return document.title;
})
.end()
.then((title) => {
console.log(title + ":" + page);
ab(page++);
//setTimeout("page(" + page + ")", 5000);
});
}
ab();
问题是您正在使用 .end()
语句结束 nightmare 会话,这会停止噩梦引擎,因此节点会在 运行 之后通过剩余的 [=12] 退出=] 语句。
为了测试你的代码,我稍微重写了你的函数,以便它抓取特定网站,并在多次找到相同页面时退出(这有点像我的测试场景,所以你可能需要调整它对于你的代码)
const Nightmare = require('nightmare')
const nightmare = Nightmare({ show: true })
function scrapePages( targetUrl, curPage = 0, transform = (url, page) => `${url}?page=${page}`, pageSet = new Set() ) {
console.info('Trying to scrape page ' + transform( targetUrl, curPage ) );
return nightmare
.goto( transform( targetUrl, curPage ) )
.evaluate( () => document.title )
.then( (title) => {
if (pageSet.has( title )) {
throw 'page already exists';
}
pageSet.add( title );
console.info( title + ':' + curPage );
return scrapePages( targetUrl, curPage + 1, transform, pageSet );
})
.catch( ( err ) => {
console.error( err );
return { maxPages: curPage, pages: pageSet };
} );
}
scrapePages( 'some-paged-url', 0, (url, page) => url + '/' + (page + 1) )
.then( ({ maxPages, pages }) => {
// end nightmare process
nightmare.end().then( () => {
console.info(`Found ${maxPages} pages`);
});
} )
.catch( err => console.error('Error occured', err ) );
最大的区别,如您所见,噩梦过程的结束仅在抓取 运行 完成后发生。届时,您将拥有可用的总页数和所有调用成功的页数