Looking for a way to extract text from web elements based on xpath. I’d like to do this by providing the macro an xpath, and any text within the element will be saved to a variable.
This is for work, so I can’t provide a specific use case. Also the web page is behind a password, so some of the solutions I’ve found by searching these forums haven’t worked thus yet. Does anyone have any ideas on how this might be accomplished?
Hello and thanks! That's very helpful. I'm a total noob though - could you perhaps explain how I get that to work? Which text do i replace? How do i fit it into a km macro?
For instance, if i get the xpath of my last post, it's:
/html/body/section/div/div[2]/div[2]/div[4]/div[3]/section/div[1]/div[2]/div/div[3]/article/div/div[2]/div[2]/div/p[1]
Where do I put that in your screenshot? Also, how does that script know what web page to look at? Seems like the xpath doesn't have any sort of URL or anything.
Sorry for the newbie questions! Thanks for any answers you can provide!
Ok, I took a stab at this, using the xpath from my first reply. I've assigned the script to write to a var. However, when I run the code, nothing happens. Any idea what I've done wrong?
I recommend using the JavaScript function querySelector rather an Xpath.
If you can provide the URL or the HTML code that contains the text you want, we can make a better suggestion.
For example, given the HTML code of this forum web page:
<div class="regular contents">
<div class="cooked">
<p>
Howdy,
</p>
<p>
Looking for a way to extract text from web elements based on xpath. I’d like to do this by providing the macro an xpath, and any text within the element will be saved to a variable.
</p>
<p>
This is for work, so I can’t provide a specific use case. Also the web page is behind a password, so some of the solutions I’ve found by searching these forums haven’t worked thus yet. Does anyone have any ideas on how this might be accomplished?
</p>
<p>
Any guidance would be greatly appreciated.
</p>
</div>
<section class="post-menu-area clearfix">
<nav class="post-controls clearfix collapsed">
<div class="actions">
<div class="double-button">
<button class="widget-button btn-flat toggle-like like no-text btn-icon" aria-label="like this post" title="like this post"><svg class="fa d-icon d-icon-d-unliked svg-icon svg-node" aria-hidden="true"><use xlink:href="#far-heart"></use></svg></button>
</div>
<button class="widget-button btn-flat share no-text btn-icon" aria-label="share a link to this post" title="share a link to this post" data-share-url="/t/looking-for-a-way-to-select-a-web-element-by-its-xpath-and-save-the-text-within-it-to-a-variable/21121?u=jmichaeltx" data-post-number="1"><svg class="fa d-icon d-icon-link svg-icon svg-node" aria-hidden="true"><use xlink:href="#link"></use></svg></button><button class="widget-button btn-flat show-more-actions no-text btn-icon" aria-label="show more" title="show more"><svg class="fa d-icon d-icon-ellipsis-h svg-icon svg-node" aria-hidden="true"><use xlink:href="#ellipsis-h"></use></svg></button><button class="widget-button btn-flat reply create fade-out btn-icon-text" aria-label="begin composing a reply to this post" title="begin composing a reply to this post"><svg class="fa d-icon d-icon-reply svg-icon svg-node" aria-hidden="true"><use xlink:href="#reply"></use></svg><span class="d-button-label">Reply</span></button>
</div>
</nav>
</section>
</div>
We can identify the HTML tag of interest as <div class="cooked">
So, we can use this JavaScript:
'use strict';
(function myMain() { // this will auto-run when script is executed
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PURPOSE: Extract Text from HTML Element
VER: 1.0 2021-01-28
AUTHOR: @JMichaelTX
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
//var kmVar = document.kmvar.VARNAME;
//var scriptResults = "TBD"
var targetElem = document.querySelector('div.cooked');
if (targetElem) {
var elemText = targetElem.innerText
} else { var elemText = '[ERROR] HTML Element NOT Found'; }
return elemText;
} // END of function myMain()
)();
Here's an example macro:
Below is just an example written in response to your request. You will need to use as an example and/or change to meet your workflow automation needs.
@JMichaelTX - this script works amazing. Thank you so so much.
One more question if it's alright - is there a way to do this action while the desired webpage is not the active window? Can it be assigned to a minimized Chrome window, while I'm working in other Chrome windows? Or is it always going to be the active window only?
Executing a JavaScript in a specific TAB in a specific Window can get complicated.
I don't have a good example to share, but maybe my friend Chris @ccstone does.
Hey Chris, thanks for the macro! This is awesome! I'm having a little trouble inputting my own user settings. I tried incorporating a line of code that JMichaelTX provided, attempting to make it read the text contents of the first element that matches the name 'div.cooked'.
Doing this did not return any results. Here is how my changes look:
This was intended to provide a somewhat dramatic example of what's possible.
Since @JMichaelTX's JavaScript is working for you the thing to do would be to use it in its entirety, rather than try to rewrite my JavaScript (which is for quite a different purpose).
JM's JavaScript is good, because it's simple, readable, and provides basic error-checking.
If you were to write it in similar fashion to mine, it would be something like:
document.querySelector('div.cooked').innerText
This is absolutely fine for one-off tasks, but for routine tasks code more like JM's is better.
Oh doh! I get it now. Sorry, I'm quite new at this! But thank you for the demo, and for this awesome script. This, combined with JMichaelTX's script is exactly what I need. You guys rock!!
@Matt_Lewis@ccstone : I wanted to reply to JMichaelTX but his account seems to be no longer active. Hopefully my question is easy enough for being my first
Question: Using the solution below as the foundation:
Could one set up a Keyboard Maestro Variable to use as malleable reference point?
Currently, this solution requires manipulation if used as a "Building Block"
I appreciate any feedback in advance
...
JMichaelTX Jan 2021
"I recommend using the JavaScript function querySelector rather an Xpath.
For example, given the HTML code of this forum web page:
We can identify the HTML tag of interest as <div class="cooked">
So, we can use this JavaScript"
***var targetElem =*** document.querySelector(***'==div.cooked=='***);
if (targetElem) {
var elemText = targetElem.innerText
} else { var elemText = '[ERROR] HTML Element NOT Found'; }
return elemText;