3

I'm working on a Greasemonkey script for weibo.com. I can't pick the elements using XPath on the XHTML page.

This code fails to grab the elements I want:

function resolver(prefix) {
    return prefix === 'x' ? 'http://www.w3.org/1999/xhtml' : null;
}
var allLinks, thisLink;
allLinks = document.evaluate(
  "//x:a[@href]", 
  document, 
  resolver, 
  XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, 
  null 
);

Only the <a> elements on the sidebar are picked and the rest are still there. Please refer to this, weibo.com, target page. 

Is there anyway to pick all the elements with attribute action-type="login"?

I used "//x:a[@action-type='login']", but It didn't work.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295

1 Answers1

5

The problem is that the script is running before all of these nodes are added to the page. They are added by the page's AJAX later.

So, you could add a time-delay to your script. But:

  1. If you just want to grab select elements, you almost never need to use XPath. Use querySelectorAll() or jQuery instead. Here's a basic example with querySelectorAll and no time delay:

    var allLinks = document.querySelectorAll ("a[action-type='login']");
    if (allLinks.length) {
        // PROCESS NODES AS DESIRED, HERE.
    }
    


  2. Here's a complete Greasemonkey script, that handles the delayed content problem using jQuery and the waitForKeyElements() utility:

    // ==UserScript==
    // @name        _Weibo, hilite login links
    // @include     http://s.weibo.com/weibo/*
    // @require     http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/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.
    */
    
    function processLoginLinks (jNode) {
        //***** YOUR CODE HERE *****
        jNode.css ("background", "lime");
    }
    
    waitForKeyElements ("a[action-type='login']", processLoginLinks);
    
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • If you don't log into weibo, the page will be different, all you get is elements with [code]action-type="login"[/code] – Dennis Chow Oct 25 '12 at 08:29
  • Actually, I got `action-type`s of: `feed_list_item`, `feed_list_media_img`, `feed_list_url`, `hover`, `login`, `remove` and `searchItem`. ... Anyway, most of us don't have and won't get a login to that site. If the logged-in page is required, save a complete snapshot of the (X)HTML to http://pastebin.com/ and link to that. ... Irregardless, my answer should work anyway, especially the second half. – Brock Adams Oct 25 '12 at 08:40
  • Hi, Brock, thanks for your kindly help, I still cannot fetch the elements, but the hint of "delayed content" quite helps, would you plz tell how to get elements in delayed content? I've read your recommmend page and I don't know how to make that using waitForKeyElements – Dennis Chow Oct 25 '12 at 08:56
  • Thanks for the detail answer, but it did not work. After checking the target page source code, I find the content are generated dynamically by script, maybe it's why I can't fetch the right elements. You can refer the target page source code here, http://www.dennispot.com/dynamic_search_result.txt, what can I do with this kind of issue? – Dennis Chow Oct 26 '12 at 01:46
  • 1
    **How** did it "not work"? What error messages did you get on Firefox's error console? Did you install the userscript I posted (item 2)? I tested it and it appeared to work perfectly -- at least on that one test page. – Brock Adams Oct 26 '12 at 01:51
  • Find a "invalid label" error from The error console, and I rename this script (just remove the comma), and It works perfectly. Big Thaaaaaaaaaaaaaaaaaanks to you, Brock~ – Dennis Chow Oct 26 '12 at 02:49