nightmare 模拟点击更多按钮,,怎么做?? - CNode技术社区

nightmare 模拟点击更多按钮,,怎么做??
发布于 8 年前 作者 Jackzhangpan 8182 次浏览 来自 问答

比如我要获取网易新闻的内容,因为是动态的,用nightmare,,但不知道怎么模拟获取更多??

var Nightmare = require('nightmare');
var nightmare = Nightmare({show:false})
nightmare
 .goto('http://news.163.com/')
 .inject('js', 'jquery.min.js')
 .type(这里应该怎么写) -------???
 .click(怎么写?) --------????
 .evaluate(function () {
 	 var newsList=[];
 $('.data_row').each(function () {
 var $me=$(this);
 var title=$me.find('.news_title').find('h3').find('a').text();
 var url=$me.find('.news_title').find('h3').find('a').attr('href');
 var item={
 title:title,
 url:url
 }
 newsList.push(item);
 })
 return newsList 	
 })
 .end()
 .then(function (result) {
 	console.log(result);
 })
 .catch(function (err) {
 	console.log(err);
 }) 
21 回复

IBQXD{SIQ@SS808ドルP{R(EM0.png

自己分析对应页面的源码,要不就找到对应的函数直接在 evaluate 调用,要不就对这个按钮模拟 click 事件。

@atian25 ,我写了click(’.load_more_btn’),但是还没有加载更多信息。网上搜了很久没找到例子,我想知道怎么去写这个click事件,,原谅我只是一个小白。

const path = require('path');
var Nightmare = require('nightmare');
var nightmare = Nightmare({
 show: true,
 pollInterval: 50
});
nightmare
 .goto('http://news.163.com/domestic/')
 .inject('js', 'jquery-2.1.1.min.js')
 .wait(function() {
 if (document.querySelector('.post_addmore').style["visibility"] == "visible") {
 document.querySelector('.load_more_btn').click();
 return false;
		}
 if (document.querySelector(".post_adding").style["display"] == "block") return false;
 if (document.querySelector(".load_more_tip").style["display"] == "block") return true;
 })
 .evaluate(function() {
 var newsList = [];
 $('.data_row').each(function() {
 var $me = $(this);
 var title = $me.find('.news_title').find('h3').find('a').text();
 var url = $me.find('.news_title').find('h3').find('a').attr('href');
 var item = {
 title: title,
 url: url
 }
 newsList.push(item);
 })
 return newsList
 })
 .end()
 .then(function(result) {
 console.log(result);
 console.log(result.length);
 }).catch(function(err) {
 console.log(err);
 })

@godghdai 感谢感谢。

@godghdai 请问一下 我这种情况 .wait(function() {}里面该怎么写 ,我写的报错

这个是爬取链接https://www.youtube.com/playlist?list=PLHPTxTxtC0iaN9kA37m6MRrxFkgby2CDR image.png https://www.youtube.com/playlist?list=PLHPTxTxtC0iaN9kA37m6MRrxFkgby2CDRimage.png

@zhoujinhai

var Nightmare = require('nightmare');
var nightmare = Nightmare({
 show: false,
 pollInterval: 50
});
nightmare
 .goto('https://www.youtube.com/playlist?list=PLHPTxTxtC0iaN9kA37m6MRrxFkgby2CDR')
 //.inject('js', 'jquery-2.1.1.min.js')
 .wait(function() {
 var loadMoreText = document.querySelector('.load-more-text');
 if (loadMoreText == null) return true;
 if (/hid/.test(loadMoreText.classList.value)) return false;
 document.querySelector('.browse-items-load-more-button').click();
 return false;
 })
 .evaluate(function() {
 return Array.from(document.querySelectorAll('.pl-video-title')).map(function(item) {
 return item.childNodes[1].innerText;
 })
 })
 .end()
 .then(function(result) {
 console.log(result);
 console.log(result.length);
 }).catch(function(err) {
 console.log(err);
 })

@godghdai 非常感谢,问题解决啦!刚接触nightmare,请问下有没有好一点儿的教程适合我这种小白的,嘿嘿

@godghdai ,我也想请问下,根据不同需求,不同的点击等事件,要怎么去分析,nightmare官网的APi ??还是有其他博客或者js教程??谢谢

@zhoujinhai @Jackzhangpan

看官网api

pollInterval (default: 250ms)
How long to wait between checks for the .wait() condition to be successful.
.wait(fn[, arg1, arg2,...])
Wait until the fn evaluated on the page with arg1, arg2,... returns true. All the args are optional. See .evaluate() for usage.

每间隔段时间都会调用wait方法,直到wait返回true,在wait方法里面根据dom检查,一般三个状态,加载中(return false),可以加载更多(click,return false),加载完毕(return true)

untitled1.png

@godghdai ,你好大神,又来请求你的帮助,像这个模拟点击下一页的问题?怎么分析去写?谢谢。

const path = require('path');
var Nightmare = require('nightmare');
var nightmare = Nightmare({
 show: false,
 pollInterval: 150
});
nightmare
 .goto('http://roll.news.qq.com/')
 .inject('js', 'jquery.min.js')
 .wait(function() {
 /////
 })
 .evaluate(function() {
 var newsList = [];
 $('#artContainer li').each(function() {
 var $me = $(this);
 var title = $me.find('a').text();
 var url = $me.find('a').attr('href');
 var item = {
 title: title,
 url: url
 }
 newsList.push(item);
 })
 return newsList
 })
 .end()
 .then(function(result) {
 console.log(result,result.length)
 }).catch(function(error) {
 console.log('错误是:'+error);
 })
 [腾讯滚动新闻](http://roll.news.qq.com/#) [腾讯滚动新闻](http://roll.news.qq.com/#)

@Jackzhangpan


var Nightmare = require('nightmare');
var nightmare = Nightmare({
 show: true,
 pollInterval: 1000
});
nightmare
 .goto('http://roll.news.qq.com/')
 .wait(function() {
 return document.querySelectorAll("#artContainer li").length>0;
 })
 .wait(function() {
 if (window._$qqNews == undefined) {
 window._$qqNews = {
 total: 0,
 page: 0,
 items: []
 }
 //停止自动刷新
 AutoRefresh();
 _$qqNews.total = qq.$("totalPage").value;
 G.showArtList = function(responseText) {
 try {
 eval("var json = " + responseText);
 if (json.response.code == "0") {
 qq.$("artContainer").innerHTML = json.data.article_info;
 //
 var newslist = document.querySelectorAll("#artContainer li a");
 for (var i = 0; i < newslist.length; i++) {
 _$qqNews.items.push({
 title: newslist[i].childNodes[0].data,
 href: newslist[i].href
 });
 }
 qq.$("totalPage").value = json.data.count;
 if (_$qqNews.total > 1) {
 _$qqNews.total -= 1;
 nextPage();
 }
 } else if (json.response.code == "2") {
 qq.$("totalPage").value = 1;
 G.gotoPage(1);
 qq.$("artContainer").innerHTML = '<div class="article-tips">该日期没有文章!</div>';
 } else {
 qq.$("totalPage").value = 1;
 G.gotoPage(1);
 qq.$("artContainer").innerHTML = '<div class="article-tips">文章加载失败!</div>';
 }
 } catch (e) {}
 }
 //加载第1页
 Refresh();
 return false;
 }
 if (_$qqNews.total == 1)
 return true;
 return false;
 }).evaluate(function() {
 return _$qqNews.items;
 })
 .end()
 .then(function(result) {
 console.log(result, result.length)
 }).catch(function(error) {
 console.log('错误是:' + error);
 })

@godghdai 谢谢谢谢。受教了,有时候分析不同页面还是一头雾水。

这个问题有意思

@godghdai 你好,不好意思又来问啦!对于其他网页模拟下一页的时候,像您15楼那样,要是找不到相应的JS文件的话,我想通过每点击一次下一页,然后获取一次页面信息,直到点到最后一页,我试了下 http://roll.news.qq.com/,但一直显示wait等待超时?请问一下,这样是我这思路不行还是代码问题!

var Nightmare = require('nightmare'); 
var nightmare = Nightmare({ 
	show: true//显示electron窗口
	// waitTimeout : 5000
});
nightmare
	//加载页面
	.goto('http://roll.news.qq.com/')
	.wait(function() {
 return document.querySelectorAll("#artContainer li").length>0;
 })
	.inject('js','jquery.min.js')
	.wait(function(){
		if(window.qqNews === undefined){
			window.qqNews={
				page : 26,
				arr : []
			};
			if(qqNews.page!==1){
	 			$('#artContainer li').each(function(){
			 		var title = $(this).find('a').text();
			 		qqNews.arr.push(title);
	 			});
	 			$('#pageArea .f12:contains("下一页")').click();
	 			qqNews.page -= 1;
	 			return false;
	 		}
	 		if(qqNews.page===1){
	 			$('#artContainer li').each(function(){
			 		var title = $(this).find('a').text();
			 		qqNews.arr.push(title);
	 			});
	 			return true;
	 		}	
		}
		return false;
	})
	.evaluate(function(){
		return qqNews.arr;
	})
	.end()
	.then(function(res){
	 console.log(res,res.length);
	})
	.catch(function (error) {
	 console.error('failed:', error);
	});

@zhoujinhai 模拟点击下一页也是可以的,只是没有上一种方法快,


var Nightmare = require('nightmare');
var nightmare = Nightmare({
 show: true //显示electron窗口
 // waitTimeout : 5000
});
nightmare
 .goto('http://roll.news.qq.com/')
 .wait(function() {
 return !document.querySelector(".loading");
 })
 .wait(function() {
 window._$qqNews = [];
 return true;
 })
 .wait(function() {
 //如果显示正在加载中......
 if (document.querySelector(".loading")) return false;
 var newslist = document.querySelectorAll("#artContainer li a");
 for (var i = 0; i < newslist.length; i++) {
 _$qqNews.push({
 title: newslist[i].childNodes[0].data,
 href: newslist[i].href
 });
 }
		//下一页button
 var next_page_button = document.querySelector("#pageArea .f12:last-child");
 if (next_page_button) {
 next_page_button.click();
 return false;
 }
 return true;
 })
 .evaluate(function() {
 return _$qqNews;
 })
 .end()
 .then(function(res) {
 console.log(res[res.length-1], res.length);
 })
 .catch(function(error) {
 console.error('failed:', error);
 });

@godghdai 嗯嗯 是的,非常感谢!!!

回到顶部

AltStyle によって変換されたページ (->オリジナル) /