有些网站的页面加载时会动态生成DOM和内容。(基于Angularjs的网站为此而臭名昭著)
您使用什么方法?我同时尝试了phantomjs和jsdom,但似乎无法在抓取之前让页面执行其javascript。
这是一个简单的jsdom示例(不是基于angularjs的,但仍是动态生成的)
var env = require('jsdom').env; exports.scrape = function(link, callback) { var config = { url: link, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36' }, done: jsdomDone }; env(config); } function jsdomDone(err, window) { var info = null; if(err) { console.error(err); } else { var $ = require('jquery')(window); console.log($('.profilePic').attr('src')); } } exports.scrape('https://www.facebook.com/elcompanies');
我尝试phantomjs取得了一定的成功。
var page = new WebPage() var fs = require('fs'); page.onLoadFinished = function() { console.log("page load finished"); window.setTimeout(function() { page.render('export.png'); fs.write('1.html', page.content, 'w'); phantom.exit(); }, 10000); }; page.open("https://www.facebook.com/elcompanies", function() { page.evaluate(function() { }); });
在这里,我等待onLoadFinished事件,甚至放一个10秒的计时器。有趣的是,尽管页面的export.png图像捕获显示了完整渲染的页面,但我的1.html并未在其应有位置显示.profilePic类元素。它似乎位于某些javascript代码中,并由某种“ require(“ TimeSlice”)。guard(function(){bigPipe.onPageletArrive({... “ block
如果您可以提供一个可以从该页面抓取图像的工作示例,那将有所帮助。
我已经通过使用nightmarejs在Facebook上做了一些抓取工作。
这是我为从Facebook页面的某些帖子中获取一些内容而执行的代码。
module.exports = function checkFacebook(callback) { var nightmare = Nightmare(); Promise.resolve(nightmare .viewport(1000, 1000) .goto('https://www.facebook.com/login/') .wait(2000) .evaluate(function(){ document.querySelector('input[id="email"]').value = facebookEmail document.querySelector('input[id="pass"]').value = facebookPwd return true }) .click('#loginbutton input') .wait(1000) .goto('https://www.facebook.com/groups/bierconomia') .evaluate(function(){ var posts = document.getElementsByClassName('_1dwg') var length = posts.length var postsContent = [] for(var i = 0; i < length; i++){ var pTag = posts[i].getElementsByTagName('p') postsContent.push({ content: pTag[0] ? pTag[0].innerText : '', productLink: posts[i].querySelector('a[rel = "nofollow"]') ? posts[i].querySelector('a[rel = "nofollow"]').href : '', photo: posts[i].getElementsByClassName('_46-i img')[0] ? posts[i].getElementsByClassName('_46-i img')[0].src : '' }) } return postsContent })) .then(function(results){ log(results) return new Promise(function(resolve, reject) { var leanLinks = results.map(function(result){ return { post: { content: result.content, productLink: extractLinkFromFb(result.productLink), photo: result.photo } } }) resolve(leanLinks) }) })
我发现对于噩梦有用的是,您可以使用wait函数来等待X ms或特定类的渲染。