比如我要获取网易新闻的内容,因为是动态的,用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);
})
自己分析对应页面的源码,要不就找到对应的函数直接在 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 https://www.youtube.com/playlist?list=PLHPTxTxtC0iaN9kA37m6MRrxFkgby2CDR
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教程??谢谢
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)
@godghdai 好的 谢谢啦
@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/#)
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 学习一下先
这个问题有意思
@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 嗯嗯 是的,非常感谢!!!