My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
ServiceIntegration  
Integration with different services
Updated Mar 29, 2012 by ariya.hi...@gmail.com

Applies to: PhantomJS 1.5.

Important: read first some basic examples, API reference, and test framework integration (Jasmine, QUnit, etc)

All of the examples given here are available in the code repository under the sub-directory examples/.

External Library

External hosted JavaScript library can be used by PhantomJS easily. See the following code snippet for an example:

page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
    // jQuery is loaded, now manipulate the DOM
});

The function includeJs behaves just like the usual dynamic script tag loading technique.

File Upload

This imagebin.js script uploads an image to imagebin.org, the popular image hosting service.

var page = new WebPage(), fname;

if (phantom.args.length !== 1) {
    console.log('Usage: imagebin.js filename');
    phantom.exit();
} else {
    fname = phantom.args[0];
    page.open("http://imagebin.org/index.php?page=add", function () {
        page.uploadFile('input[name=image]', fname);
        page.evaluate(function () {
            document.querySelector('input[name=nickname]').value = 'phantom';
            document.querySelector('input[name=disclaimer_agree]').click()
            document.querySelector('form').submit();
        });
        window.setTimeout(function () {
            phantom.exit();
        }, 3000);
    });
}

JSONP

JSONP is easy to do, following the usual loading technique via the src attribute of the script tag.

This ipgeocode.js script shows the approximated location based on the network IP address, using freegeoip JSONP API.

var cb = function (data) {
    var loc = data.city;
    if (data.region_name.length > 0)
        loc = loc + ', ' + data.region_name;
    console.log('IP address: ' + data.ip);
    console.log('Estimated location: ' + loc);
    phantom.exit();
};

var el = document.createElement('script');
el.src = 'http://freegeoip.net/json/?callback=cb';
document.body.appendChild(el);

Example output:

 IP address: 75.25.137.196
 Estimated location: Palo Alto, California
 

YQL

Integration with YQL system can be achieved via the same JSONP approach.

The example movies.js here using the query to pull the listed movies from kids-in-mind.com:

var cbfunc = function (data) {
    globaldata= data;
    var list = data.query.results.movie;
    list.forEach(function (item) {
        console.log(item.title + ' [' + item.rating.MPAA.content + ']');
    });
    phantom.exit();
};

var el = document.createElement('script');
el.src = 'http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20movies.kids-in-mind&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=cbfunc';
document.body.appendChild(el);

which will give:

Chronicles of Narnia: Voyage of the Dawn Treader [PG]
The Tourist [PG-13]
Black Swan [R]
Little Fockers [PG-13]
True Grit [PG-13]
Somewhere [R]
TRON: Legacy [PG]

As another example, the following seasonfood.js displays the list of seasonal food from BBC GoodFood query.

var cbfunc = function (data) {
    var list = data.query.results.results.result,
        names = ['January', 'February', 'March',
                 'April', 'May', 'June',
                 'July', 'August', 'September',
                 'October', 'November', 'December'];
    list.forEach(function (item) {
        console.log([item.name.replace(/\s/ig, ' '), ':',
                  names[item.atItsBestUntil], 'to',
                  names[item.atItsBestFrom]].join(' '));
    });
    phantom.exit();
};

var el = document.createElement('script');
el.src = 'http://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20bbc.goodfood.seasonal%3B&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=cbfunc';
document.body.appendChild(el);

such as:

 Apricot : September to May
 Blackberry : September to September
 Blackcurrant : August to July
 Blueberry : August to July
 Bramley apple : December to October
 Broad beans : September to July
 

XML

Instead of asynchronous XML HTTP request, often it is simpler to load the XML directly into the web page and then use standard DOM scripting and CSS selectors.

The following weather.js script displays the weather data and forecast information for a specified location, obtained via Google Gadget Weather.

var page = new WebPage(),
    address = "Mountain View";

page.onConsoleMessage = function(msg) {
    console.log(msg);
};

page.open(encodeURI('http://www.google.com/ig/api?weather=' + address), function (status) {
    if (status !== "success") {
        console.log("Unable to access network");
    } else {
        page.evaluate(function() {
            if (document.querySelectorAll('problem_cause').length > 0) {
                console.log('No data available for ' + address);
            } else {
                function data (s, e) {
                    var el;
                    e = e || document;
                    el = e.querySelector(s);
                    return el ? el.attributes.data.value : undefined;
                };

                console.log('City: ' + data('weather > forecast_information > city'));
                console.log('Current condition: ' + data('weather > current_conditions > condition'));
                console.log('Temperature: ' + data('weather > current_conditions > temp_f') + ' F');
                console.log(data('weather > current_conditions > humidity'));
                console.log(data('weather > current_conditions > wind_condition'));
                console.log('');

                var forecasts = document.querySelectorAll('weather > forecast_conditions');
                for (var i = 0; i < forecasts.length; ++i) {
                    var f = forecasts[i];
                    console.log(data('day_of_week', f) + ': ' +
                        data('low', f) + '-' + data('high', f) + ' F  ' +
                        data('condition', f));
                }
            }
        });
    }
    phantom.exit();
});

When it is invoked:

phantomjs weather.js

The output looks like:

 City: Mountain View, CA
 Current condition: Clear
 Temperature: 50 F
 Humidity: 80%
 Wind: N at 0 mph
 Mon: 47-57 F  Partly Cloudy
 Tue: 49-58 F  Showers
 Wed: 40-53 F  Windy
 Thu: 40-54 F  Partly Cloudy
 

Another example herebelow, direction.js, gets driving direction between two locations using Google Directions API.

var page = new WebPage(),
    origin, dest, steps;

if (phantom.args.length < 2) {
    console.log('Usage: direction.js origin destination');
    console.log('Example: direction.js "San Diego" "Palo Alto"');
    phantom.exit(1);
} else {
    origin = phantom.args[0];
    dest = phantom.args[1];
    page.open(encodeURI('http://maps.googleapis.com/maps/api/directions/xml?origin=' + origin +
                '&destination=' + dest + '&units=imperial&mode=driving&sensor=false'), function (status) {
        if (status !== 'success') {
            console.log('Unable to access network');
        } else {
            steps = page.content.match(/<html_instructions>(.*)<\/html_instructions>/ig);
            if (steps == null) {
                console.log('No data available for ' + origin + ' to ' + dest);
            } else {
                steps.forEach(function (ins) {
                    ins = ins.replace(/\&lt;/ig, '<').replace(/\&gt;/ig, '>');
                    ins = ins.replace(/\<div/ig, '\n<div');
                    ins = ins.replace(/<.*?>/g, '');
                    console.log(ins);
                });
                console.log('');
                console.log(page.content.match(/<copyrights>.*<\/copyrights>/ig).join('').replace(/<.*?>/g, ''));
            }
        }
        phantom.exit();
    });
}

When it runs as follows:

phantomjs direction.js 'San Diego' 'Palo Alto'

it gives the following result:

 Head south on 8th Ave toward E St
 Take the 1st left onto E St
 Turn left at the 3rd cross street onto 11th Ave
 Continue onto CA-163 N
 Take exit 7A to merge onto I-805 N toward Los Angeles
 Merge onto I-5 N
 Take exit 403B to merge onto CA-152 W/CA-33 N toward Gilroy/Hollister/San Jose
 Continue to follow CA-152 W
 Slight right at CA-152 W/Pacheco Pass Hwy
 Turn left at CA-152 W/Pacheco Pass Rd
 Merge onto US-101 N via the ramp to San Jose
 Take exit 402 for Embarcadero Rd toward Oregon Expy
 Keep right at the fork and merge onto Oregon Expy
 Turn right at Middlefield Rd
 Destination will be on the left
 

Comment by klaus.ha...@gmail.com, Mar 21, 2011

Found that in the Jasmine driver the selector for .finished_at needs to be finished-at, that might have changed in some past release...

Comment by nicktul...@yahoo.com, Mar 22, 2011

I think you might have your fruity months the wrong way round in the YQL example.

Comment by project member alessandro.portale, Mar 24, 2011

@tushar: phantomjs does not have that feature (yet). There is a feature request for it.

Powered by Google Project Hosting