12 Replies Latest reply: Oct 15, 2012 9:34 AM by Queerly
Queerly Level 1 Level 1 (0 points)

Hi, I'm new to AppleScript but learning fast. However, JavaScript is still marked as "there be dragons" for me, though I've made some progress already.

 

Anyways, I'm facing the follwing conundrum: I managed to write an AppleScript to fill in a Search Querry on a WebPage using JavaScript, however, I can't manage to get JavaScript to do the last step, i.e. press the "Submitt button", as it has no ID or Name associated with it. The button is defined as follows:

 

<input type=​"submit" value=​"Search...搜索... ">​

 

I've tried something on the lines of:

--do JavaScript "document.getElementsByTagName('submit')[0].submit()" in document 1

 

or

 

--do JavaScript "document.getElementsByTagName('submit')[0].click()" in document 1

 

but to no avail.

 

What should the JavaScript Command look like? Could anybody help?


MacBook Pro, Mac OS X (10.7.4)
  • 1. Re: Clicking JavaScript element without Name or ID
    twtwtw Level 5 Level 5 (4,690 points)

    well, first off, the tag name would be 'input' not 'submit'.  you'd want to try document.getElementsByTagName('input') and search through the resultant nodes for the correct one.  However, it would be helpful to see more of the html.  for instance, if the submit button is inside an html form, you can identify it more easily by finding the form first.

  • 2. Re: Clicking JavaScript element without Name or ID
    Queerly Level 1 Level 1 (0 points)

    Thank you twtwtw,

     

    it worked like a charm. I followed your advice and used trial and error method to find which node would work. This worked for me:

     

    do JavaScript "document.getElementsByTagName('input')[11].click()

     

    Actually, I had been so close to finding the solution on my own, cos I was trying both 'input' and 'submit' before, only up to [10]. Still, I'm glad I asked, otherwise I'd not have learned about those nodes. I'll have to read up some more on that topic later, to understand it some more.

     

    Accidentally, is there any cleaverer way to find out which node that would be, than just trial and error? Can you tell me how? The webpage can be found here: http://hua.umf.maine.edu/php/search.php

  • 3. Re: Clicking JavaScript element without Name or ID
    twtwtw Level 5 Level 5 (4,690 points)

    Actually, there is an easier way.  The submit button is within a FORM element with the name 'com'.  As such, you don't even need to click the button.  Just submit the form programmatically using this code:

     

    document.forms['com'].submit()

     

    And you need to get control of your auto-correct.  I mean seariously: "Accidentally, is there any cleaverer way..."? 

  • 4. Re: Clicking JavaScript element without Name or ID
    Queerly Level 1 Level 1 (0 points)

    Oh, btw, is it too mutch to pick your brain on a similar matter? If you have a minute or two, could you glance at the following post:

     

    https://discussions.apple.com/thread/4425159

     

    Looking forward to any tips or sollutions.

  • 5. Re: Clicking JavaScript element without Name or ID
    Queerly Level 1 Level 1 (0 points)

    Your comment made me laugh, honestly. I could try to wriggle my way out of it by saying that I was trying to be creative by inventing a new word that would convey the idea of being "clever" and at "cutting-edge solution" (accidentally, cleaverer would fit the bill quite nicely, but I won't try, because I think you're too smart to buy it.

     

    Instead, I'm just going to make the valid excuse that English is not my mother tongue.

     

    Oh, and as for the more ellegant solution. I'm going to stick with the working sollution I have for the time being, because I'm a bit pressed for time and I code really slow. But once I have some more time on my hands, I'm going to read up a bit on JavaScript and give it a try.

  • 6. Re: Clicking JavaScript element without Name or ID
    Queerly Level 1 Level 1 (0 points)

    I actually ended up using the document.forms['com'].submit() as you adviced. Works just as well. Thx for your time.

  • 7. Re: Clicking JavaScript element without Name or ID
    Queerly Level 1 Level 1 (0 points)

    @twtwtw

     

    I've been testing my script on large chunks of data, some 4k items long, and it's working really well, most of the time. However, I have two things I'd like to ask you:

     

    1) For one reason or another, it occasionally happens that the "document.forms['com'].submit()" command suddenly stops working. The script continues running, new items are entered into the search field, but the form doesn't get submitted. For the time being, I've modified the script to get it submitt the form first, and then click the submit button just in case. I also made it refresh the page each time before running javascript. Don't know if it will work. It's hard to replicate the problem. I run the script in the background with Saphari minimised, while I use my computer as usual (just using Firefox for browsing instead) so it may be getting some interference from user actions. Any ideas what it may be?

     

    2) The script is processing large amounts of entries. Basically it enters the search term in the serch field of the online dictionary and goes through the results one by one, adding them to my study list. Before that, however, it checks if the entry has not already been added before (different search terms can produce the same results). The problem is, some search terms produce up to 500 results, and then AppleScript gets really(!) busy, and the fans in my mac spin like crazy. Once it gets through those entries, it returns to normal. But since I have like thousands of thousands of results to through, I'm not sure wheter it wouldn't affect the lifespan of my precious mac in the long haul. Have you had similar problems when scripting? Is there any way to manage the resources effectively in AppleScript? I was thinking maybe of a delay command at the end of such loops, when an item is skipped, but what would be the reasonable delay time?

  • 8. Re: Clicking JavaScript element without Name or ID
    twtwtw Level 5 Level 5 (4,690 points)

    Queerly wrote:

     

    1) For one reason or another, it occasionally happens that the "document.forms['com'].submit()" command suddenly stops working.

     

    2) The problem is, some search terms produce up to 500 results, and then AppleScript gets really(!) busy, and the fans in my mac spin like crazy. Once it gets through those entries, it returns to normal.

     

    1) Submit may not work before the page is fully loaded, so if (for some reason) the page loads slowly and the command gets sent too soon...  You could add in a repeat loop to check if the page is fully loaded, like so:

     

    tell application "Safari"

              repeat until ((do JavaScript "document.readyState" in document 1) = "complete")

      delay 1

              end repeat

    end tell

     

    but be aware that if the page doesn't load the script will get caught in an infinite loop and need to be quit using Command-..

     

    2) first, I suspect you can probably improve your search function. If you are searching through the entire list of done characters in a repeat loop, you're wasting tons of resources.  Do it this way instead:

     

    property doneTheseAlready : {}

     

    -- when you get a new character to test, do it this way

    if thisCharacter is in my doneTheseAlready then

      -- skip and move on to next

    else

      -- save this character as completed

              copy thisCharacter to end of my doneTheseAlready

      -- do whatever downloading/processing you need to do

    end if

     

    That pushes the search off onto applescript itself, which is tremendously more efficient.  As a bonus, setting it as a property means you can quit the script and it will remember the list when you start up again.  Don't worry about it being Chinese characters; applescript handles unicode just fine.

     

    That being said, having your fans run high is not going to hurt anything - they are designed to do that.  Assuming you haven't blocked the vents, the fans are more than capable of keeping the machine within recommended operating temperatures.

  • 9. Re: Clicking JavaScript element without Name or ID
    Queerly Level 1 Level 1 (0 points)

    Thx again for your advice,

     

    1) I don't think, however, that the page not being fully loaded is the problem. I had been using a following function to load the url. It's practically the same as yours. (I put the delay time in a variable, because some sites I use take longer to reply on different days, so I can adjust it accordingly at the head of applescript code.

     

    on LoadURL(theURL, DelayTimeLong)

        tell application "Safari"

            set URL of document 1 to theURL

            delay DelayTimeLong

            repeat

                ----use Safari's 'do JavaScript' to check a page's status

                if (do JavaScript "document.readyState" in document 1) is "complete" then exit repeat

                delay 1

            end repeat

        end tell

    end LoadURL

     

     

    ad 2) I've been using a similar sollution, where I would use applescript to store the processed entries in its cashe by calling:

     

    set ProcessedCashe to ProcessedCashe & CharacterEntry --ensures that the entry won't be duplicated

     

    and checking the uniquness of each new search result by using:

     

    on CheckIfUnique(CharacterEntry, ProcessedCashe)

        set UniquenessValue to "unique"

        repeat with p from 1 to count of ProcessedCashe

            --display dialog CharacterEntry & return & "vs." & return & item p of ProcessedCashe

            if item p of ProcessedCashe is CharacterEntry then

                set UniquenessValue to "duplicate"

                exit repeat

            end if

        end repeat

        return UniquenessValue

    end CheckIfUnique

     

    but as you see, it was yet again another loop. I remember I wanted just to bypass the loop and use something along the lines of:

     

    if ProcessedCashe contains CharacterEntry then

    -- skip

    else

    --proceed

    end if

     

    but for one reason or another couldn't get it to work. I'll give your sollution a try soon. I think it might be more efficient. At the moment, I'm using a delay 0.3 after each skipped item, which prevents my fans from spinning out of controll, although I've noticed that the average speed per character is much lower.

     

    Comparing your sollution to mine, I'm starting to suspect the problem is cummulative throughout the entire code, not just one function. I'm new to AppleScript, and though I can get it to do what I want (having picked the brains of people like you, I might add), I probably don't get it to do these things in the most efficient way.

     

    I'll have to try to improve with with time.

  • 10. Re: Clicking JavaScript element without Name or ID
    twtwtw Level 5 Level 5 (4,690 points)

    1) well, the other option is that the page itself has some occasional irregularity that mucks up the DOM.  That couyld be jsut about anything (e.g. a miscode in PHP that sometimes drops or changes the name of the form element).  Unless I can see the html of the page on one of the times it doesn't work, your guess is as good as mine.

     

    2) yeah, it takes a while to learn the ins and outs of applescript.  it has intuitive tricks and shortcuts that you jsut have to learn.  If you want to post the full script (assuming it's not too long) I can help you optimize it, but I'm pretty sure the repeat loop you're using above is the source of your fan problem.

  • 11. Re: Clicking JavaScript element without Name or ID
    Queerly Level 1 Level 1 (0 points)

    Hi twtwtw,

     

    It's really nice of you to offer your help, but the code is a bit long, so I don't want to trouble you. I'll just try implementing the solution from the previous post and tell you how it went. When writing a code next time, I'll try finding alternative solutions to loops.

     

    The double implementation of clicking the button and submitting the form makes the problem occurr less often. I save all the results to a log anyway, so I can trace the first entry that failed and resume the search from there.

     

    Cheers!

  • 12. Re: Clicking JavaScript element without Name or ID
    Queerly Level 1 Level 1 (0 points)

    Hi,

     

    I optimised the code according to your suggestions, and tweeked the code here and there a bit. It's like magic. The fans don't spin up any more, and the average processing speed has gone up from the original 2.2 words a minute to 9.2.

     

    Thx again.