3

I am attempting to make a simple nodejs client that will eventually crawl a given reddit users profile history. Right now i am trying to use the jsdom module to extract the URL for the next page of results on a given users profile.

I am currently working in ubuntu 12.10 and my versions of npm and nodejs are current.

Here is the code that i have so far. I will include the error message below.

var http = require('http'),
    jsdom = require('jsdom');

//object containing http.request options
//path accepts a username via process.argv[2]
var options = {
    host: 'www.reddit.com',
    path: '/user/' + process.argv[2]
};

//getPage requests the page for a given user
function getPage() {

    var req = http.request(options, function(response){
        response.setEncoding('utf8');

        response.on('data', function(rawHTML){
            // console.log(data);
            setNextPage(rawHTML);
        });
        response.on('error', function(error){
            console.log(error);
        });
        response.on('end', function(){
            console.log('Response complete');
        });
    });

    req.end();
}

//the setNextPage function combs the rawHTML sent to it,
//extracting the URL for the next page of a users history

function setNextPage(rawHTML) {
    jsdom.env(
        rawHTML,
        ["http://code.jquery.com/jquery.js"],
        function(errors, window) {
            var nextPageURL = window.$(".nextprev > a").attr("href");
            console.log('URL for the next page is: ' + nextPageURL);
        }
    );
}

getPage();

Now for the error message that i am getting after running the client.

/home/stephen/Desktop/getKarma/app.js:38
            var nextPageURL = window.$('.nextprev > a').attr("href");
                                     ^
TypeError: Object #<Object> has no method '$'
    at /home/stephen/Desktop/getKarma/app.js:38:29
    at exports.env.exports.jsdom.env.scriptComplete (/home/stephen/Desktop/getKarma/node_modules/jsdom/lib/jsdom.js:205:39)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

There's an interesting pattern worth mentioning here: a JavaScript constructor may return any object (not necesserily this). One could create a constructor function, that returns a proxy object, that contains proxy methods to the "real" methods of the "real" instance object. This may sound complicated, but it is not; here is a code snippet:

var MyClass = function() {
    var instanceObj = this;
    var proxyObj = {
        myPublicMethod: function() {
            return instanceObj.myPublicMethod.apply(instanceObj, arguments);
        }
    }
    return proxyObj;
};
MyClass.prototype = {
    _myPrivateMethod: function() {
        ...
    },
    myPublicMethod: function() {
        ...
    }
};

The nice thing is that the proxy creation can be automated, if we define a convention for naming the protected methods. I created a little library that does exactly this: http://idya.github.com/oolib/

4

0 回答 0