To use this script, you need to a) use the firefox web-browser and b) install the "greasemonkey" addition to firefox. A similar script (maybe almost identical script) should work with imacro, or IE7pro for other browsers. This script if fully documented so you can see what it is suppose to do.
To use this script you can copy and paste and save the script somewhere to load it into your firefox, or you can use the following link to load it into firefox (with greasemonkey addition already installed)... http://tinyurl.com/kwdc28b (note this link only works with firefox).
It seems to lose the East player name for the first few cells of the data you retrieve but other than that, the data looks correct and most importantly, you can cut and paste myhands results directly into excel and then use GetURL function to extract as text the information contained under the "movie" link.
// ==UserScript== // @name BridgeBase Munger // @namespace [url="http://hostilefork.com/"]http://hostilefork.com[/url] // @description Modifies a bridgebase formatting // @require [url="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"]http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js[/url] // @include [url="http://www.bridgebase.com/myhands/hands.php"]http://www.bridgebase.com/myhands/hands.php[/url]* // @version 1 // ==/UserScript== try { // "Query" the page using the $() operator. This particular query // pattern looks for any table cells <td> with the class "movie". For // more information on the kinds of patterns you can look for, see: // // [url="http://api.jquery.com/category/selectors/"]http://api.jquery.com/category/selectors/[/url] // // We then use .each to call a function on each element that was found. $('td.movie').each(function() { // the "this" context variable indicates for us the current <td> // element in our enumeration. We "enhance it" with more methods // by using the $ operator...since we aren't passing it a string, // it doesn't interpret that as a query but a desire to "wrap up" // the native underlying web browser item. When some people do // such augmentations, they will name the variable with a leading $ // by convention to help differentiate them. var $td = $(this); // Currently the movie table element contains two HTTP anchor links // (the "A" in <A HREF="whatever"> is for "anchor") // They are labeled "Movie" and "Lin". We want to take the one that // links to the handviewer.html and use its onclick property to replace // the entire contents of the cell. // As before we use a jQuery query string, simply looking for all // anchors underneath the current table element. .find will do a // query from under an element of this type. Again we enumerate. $td.find('a').each(function() { // And again, we augment the browser DOM element with some special // powers, and name the variable with a leading $ sign var $a = $(this); // What test we use to decide if we're looking at the right // anchor is up to us. We could see if it was named "Movie", // or if it was the first one in the table, etc. It's not really // possible to predict how a page might change if it's not under // your control. But looking for the string "handviewer.html" in // the anchor seems like a safe enough bet. If the position we // find of that string is not -1, then it has at least one instance // in the string. if ($a.attr('href').indexOf('handviewer.html') != -1) { // Capture the onclick attribute into a variable, and then // remove it from the anchor. That way the hyperlink we // produce will have the same behavior with or without // JavaScript...and easier to test in the browser. var onclickString = $a.attr('onclick'); $a.attr('onclick', ''); // The onclick string invokes a JavaScript function called // hv_popuplin to make a popup window. It starts like this: // // hv_popuplin('pn|south,west,north,east|st%7C%7Cmd%... // // And ultimately it ends something like this: // // ...%7Cmc%7C7%7C');this.style.color='red';return false; // // We want the string inside the parentheses. var matchArray = onclickString.match(/\.*\('(.+)'\).*/); if (matchArray.length < 2) { throw Error("No LIN string match in " + onclickString); } else if (matchArray.length > 2) { throw Error("Multiple LIN string match in " + onclickString); } var linString = matchArray[1]; // Now we want to make a proper hyperlink out of that string. var viewerUrl = "/tools/handviewer.html?lin=" + linString; // Set the anchor to our updated hyperlink $a.attr('href', viewerUrl); // Detach the hyperlink, clear everything else out of the table // cell, and then append the hyperlink as the sole element // IMPORTANT NOTE: When we make these modifications, they will // not be reflected if you "View Source". Because we aren't // changing the HTML text file...we are manipulating the // browser's structure. One needs to use the browser's // debugging tools to see the effects. $a.detach(); $td.empty(); $td.append($a); // Returning false will break out of the .each enumeration, // so we shouldn't visit any other hyperlinks in the set return false; } }); }); } catch (err) { // If an error was thrown, go ahead and present it as an alert to help // with debugging any problems alert(err.toString()); }