4

I'm creating a Greasemonkey script which reads and stores information from a text-based game into a database to use in the future.

What I want is to be able to read the user's stats and turn those stats into variables so that I can proceed with making the information useful.

Here is the source code of the table which I want to grab the stats info from:

<table width="100%">
  <tr>
    <td width="50%" valign="top" style="padding-right: 25px;">
      <table class="table_lines" width="100%" cellspacing="0" cellpadding="6" border="0">
        <tr>
          <th colspan="3">Military Effectiveness</th>
        </tr>
        <tr>
          <td><b>Strike Action</b></td>
          <td align="right">16,376,469,657</td>
          <td align="right">Ranked #443</td>
        </tr>
        <tr>
          <td><b>Defensive Action</b></td>
          <td align="right">4,016,716,436</td>
          <td align="right">Ranked #569</td>
        </tr>
        <tr>
          <td><b>Spy Rating</b></td>
          <td align="right">12,245,896</td>
          <td align="right">Ranked #1,204</td>
        </tr>
        <tr>
          <td><b>Sentry Rating</b></td>
          <td align="right">5,291,630,090</td>
          <td align="right">Ranked #831</td>
        </tr>
      </table>

Now as you can see the stats don't have identifying class IDs or anything, so I'm not sure how to do this. I only really use PHP, so JavaScript is very new to me but it seems similar to PHP.

Maybe something that says "After <td><b>Strike Action</b></td>, grab the first td value" and then put it as a variable?

NOTE: Strike Action, Defensive Action, Spy Rating, and Sentry Rating are the variables I need.

double-beep
  • 5,031
  • 17
  • 33
  • 41
Billy Rammal
  • 115
  • 1
  • 2
  • 8

4 Answers4

3
  1. Use jQuery to make parsing the table easier.
  2. Since you want the rating, don't forget to parse the numbers into javascript integers.
  3. If the page is AJAX-driven, use AJAX-aware techniques.

Here is a complete Greasemonkey/Tampermonkey script showing how to do all of that:

// ==UserScript==
// @name     _Parse table information that has low information scent.
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @include  http://bilalrammal.ca/clicker/tester.html
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/
waitForKeyElements (".table_lines", parseMilitaryEffectivenessTable);

function parseMilitaryEffectivenessTable (jNode) {
    //--- Note that :contains() is case-sensitive.
    var strikeAction    = jNode.find ("tr:contains('Strike Action') td:eq(1)").text ();
    var defensiveAction = jNode.find ("tr:contains('Defensive Action') td:eq(1)").text ();
    var spyRating       = jNode.find ("tr:contains('Spy Rating') td:eq(1)").text ();
    var sentryRating    = jNode.find ("tr:contains('Sentry Rating') td:eq(1)").text ();

    //--- Convert strings to integers...
    strikeAction        = parseInt (strikeAction   .replace (/\D/g, ""), 10);
    defensiveAction     = parseInt (defensiveAction.replace (/\D/g, ""), 10);
    spyRating           = parseInt (spyRating      .replace (/\D/g, ""), 10);
    sentryRating        = parseInt (sentryRating   .replace (/\D/g, ""), 10);

    //--- Show on console:
    console.log ("strikeAction: ",       strikeAction);
    console.log ("defensiveAction: ",    defensiveAction);
    console.log ("spyRating: ",          spyRating);
    console.log ("sentryRating: ",       sentryRating);
}
Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • One last thing, how do I make it so it only pinpoints the Strike Action value of the td who's parent is the th who's value is "Military effectiveness"? Since there might be other things that'll say strike action on the page – Billy Rammal Nov 15 '15 at 07:17
  • If there is more than one table with the class `table_lines`, and they all aren't "Military Effectiveness", Then adjust the selector used in `waitForKeyElements()`. Something like: `".table_lines:contains('Military Effectiveness')"` is one way. If it's something else, make a new question. – Brock Adams Nov 15 '15 at 07:22
1

You would assign it an id and grab it using the getElementById javascript method:

HTML

<div id="something">Test</div>

JAVASCRIPT

var value = document.getElementById("something").value;
//value = "Test";

But, if you are trying to get the content from a page that is not your own, xpath is one way to go:

function getElement(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

var rows = getElement("//html[1]/body[1]/table[@class='table_lines']/tr");

That would return an array of all the table rows.

jrkt
  • 2,615
  • 5
  • 28
  • 48
  • 1
    There is no ID, that's what I'm saying: I can't assign it an ID myself as it's not my own page, it's a page that GreaseMonkey is running on to read the info. – Billy Rammal Nov 15 '15 at 05:29
  • Ah, I misread that. You could look into xpath. That would get the job done. – jrkt Nov 15 '15 at 05:30
  • Yes that would probably work actually - but I have no idea how to implement it.. Maybe an example for the first variable and I could get how to work it - my javascript is very bad – Billy Rammal Nov 15 '15 at 05:38
1
list.getElementsByTagName("tag").innerHTML = "html text";

This might be able to to work as well

spe
  • 65
  • 10
1

Try something like this (note you will need to use jquery library for this to work)

$(".table_lines").find('tr').each(function (i) {
    var $tds = $(this).find('td'),
        lable = $tds.eq(0).text(),
        value = $tds.eq(1).text(),
        rank = $tds.eq(2).text();
    // do something with lable, value, rank
    alert('Lable: ' + lable + '\nValue: ' + value + '\nRank: ' + rank);
})
naw103
  • 1,843
  • 1
  • 15
  • 14