Question: I'm into some web scraping with Node.js. I'd like to use XPath as I can generate it semi-automatically with several sorts of GUI. The problem is that I cannot find a way to do this effectively.

1. `jsdom` is extremely slow. It's parsing 500KiB file in a minute or so with full CPU load and a heavy memory footprint.
2. Popular libraries for HTML parsing (e.g. `cheerio`) neither support XPath, nor expose W3C-compliant DOM.
3. Effective HTML parsing is, obviously, implemented in WebKit, so using `phantom` or `casper` would be an option, but those require to be running in a special way, not just `node <script>`. I cannot rely on the risk implied by this change. For example, it's much more difficult to find how to run `node-inspector` with `phantom`.
4. `Spooky` is an option, but it's [buggy enough](https://github.com/WaterfallEngineering/SpookyJS/issues/71), so that it didn't run at all on my machine.

What's the right way to parse an HTML page with XPath then?

Answer: 
[Libxmljs](https://github.com/polotek/libxmljs) is currently the fastest implementation (something [like a benchmark](https://github.com/blue-button/bluebutton.js/issues/97)) since it's only bindings to the [LibXML](http://xmlsoft.org/) C-library which supports XPath 1.0 queries:

```
var libxmljs = require("libxmljs");
var xmlDoc = libxmljs.parseXml(xml);
// xpath queries
var gchild = xmlDoc.get('//grandchild');

```

However, you need to sanitize your HTML first and convert it to proper XML. For that you could either use the [HTMLTidy](http://tidy.sourceforge.net/) command line utility (`tidy -q -asxml input.html`), or if you want it to keep node-only, something like [xmlserializer](https://www.npmjs.org/package/xmlserializer) should do the trick.
I think [Osmosis](https://github.com/rchipka/node-osmosis) is what you're looking for.

> 
> * Uses native libxml C bindings
> * Supports CSS 3.0 and XPath 1.0 selector hybrids
> * Sizzle selectors, Slick selectors, and more
> * No large dependencies like jQuery, cheerio, or jsdom
> * HTML parser features
> 
> 
> 	+ Fast parsing
> 	+ Very fast searching
> 	+ Small memory footprint
> * HTML DOM features
> 
> 
> 	+ Load and search ajax content
> 	+ DOM interaction and events
> 	+ Execute embedded and remote scripts
> 	+ Execute code in the DOM
> 
> 
> 

[Here's an example:](https://github.com/rchipka/node-osmosis/blob/9c23441187950febc3e605b843a1295064c13550/test/find.js#L71)

```
osmosis.get(url)
    .find('//div[@class]/ul[2]/li')
    .then(function () {
        count++;
    })
    .done(function () {
        assert.ok(count == 2);
        assert.done();
    });

```