How to get innerHTML with Xpath javascript? - javascript

I need to retrieve text from inner element. With php it so easy to use Xpath. how about in javascript? I need to retrieve from specific element with specific id too. the request under code below. Let say it doesnt problem with CORS. i installed chrome extension to solve CORS.
<html>
<head>
</head>
<body>
<script>
fetch('https://alexistogel1.blogspot.com/2019/08/post-tak-penting.html')
.then(function (response) {
return response.text();
})
.then(function (html) {
var element = document.evaluate( "//div[#id='post-body-6034358444211110141']" ,document, null, XPathResult.ANY_TYPE, null );
console.log(element);
});
</script>
</body>
</html>

Use a DOMParser to convert your string to a document.
Now you can use the document to select the element inside it with the help of getElementById.
fetch('https://alexistogel1.blogspot.com/2019/08/post-tak-penting.html')
.then(function (response) {
return response.text();
})
.then(function (text) {
const parser = new DOMParser();
return parser.parseFromString(text, 'text/html');
})
.then(function (html) {
var element = html.getElementById('post-body-6034358444211110141');
console.log(element.innerHTML);
});

Related

I am trying to display a quote after typing author name in the textbox but for some reason it is not displaying anything. How should I fix this?

I am getting undefined when I type the author name in the text box and press the button to display the quote. It seems like my button and textbox are not linked together. How can I fix this?
<!DOCTYPE html>
<html lang="en">
<head>
<title>Quotes</title>
</head>
<body>
<label for="getQuotes">Find Quotes (Type Author Name)</label><br>
<input type = "text" id="getQuotes" name="getQuotes" placeholder="Search" style="margin:10px" size="50"/><br />
<button id="FetchQuotes" onclick="getQuote()" style="margin:10px">Fetch Quotes</button>
<p id="quotes"></p>
<p id="author"></p>
<script>
async function getQuote() {
//const author = Boolean(false);
let url = 'https://jaw1042-motivate.azurewebsites.net/quote';
let author = document.getElementById('getQuotes').value;
if(author) {
url = 'https://jaw1042-motivate.azurewebsites.net/quote?author= ';
console.log(url + author);
} else {
console.log(url);
}
fetch(url)
.then(async (response) => {
if (response.ok) {
console.log("Response code: " + response.status);
} else if (response.status === 400) {
console.log("Unable to find any quotes by specified author: " + response.status);
} else {
console.log("No quotes have been loaded: " + response.status);
}
const val = await response.json();
console.log(val);
}).then(data => {
document.getElementById('quotes').value = data;
document.getElementById('author').value = data;
console.log(data);
alert(data);
});
}
</script>
</body>
</html>
your then functions are not correct
in the direct result of the fetchAPI you can receive data and to use it you need to run .json() or .text() on it, you can't simply use that result or return it's value ( plus when you use return statement all your next codes will be unreachable)
after that you should not assign something to your data variable because it just has new Data fetched from backend, by assigning new value to data you're about to ruin new data
here is how your js should look
function getQuote() {
fetch("https://krv1022-motivate.azurewebsites.net/quote")
.then( res => res.text() )
.then( data => {
document.querySelector(".quote").value = data;
}
);
}
I also provided a fiddle for it but it can't receive data because either your URL is not correct or there is CORS issues
==============================================
one thing that I just noticed, you are receiving Author's name from end user but you are not about to send it to backend!
so perhaps this code is more complete, I assume that you want to send data using GET method and backend wants the name of author to be named getQuotes

How can I get a text from a div?

I'm trying to get a piece of text that is inside a <div class> of a especific URL and return only the content inside the <a title>. Like "<div class="test"><a title="Hello World"></a></div>" and return Hello World.
But I don't know what should do to return pieces of the text, it's returning whole html.
const fetch = require("node-fetch");
fetch('https://www.google.com/')
.then(function (response) {
switch (response.status) {
// status "OK"
case 200:
return response.text();
// status "Not Found"
case 404:
throw response;
}
})
.then(function (template) {
console.log(template)
console.log("DONE");
})
.catch(function (response) {
// "Not Found"
console.log(response.statusText);
});
fetch('https://www.myear.sg/test.php')
.then(function (response) {
switch (response.status) {
// status "OK"
case 200:
return response.text();
// status "Not Found"
case 404:
throw response;
}
})
.then(function (template) {
console.log(find_id_details (template))
document.getElementById("abc").innerHTML = find_id_details (template)
})
.catch(function (response) {
// "Not Found"
console.log(response.statusText);
});
function find_id_details (input){
var part1 = input.split('<div id="abcd">')[1];
var part2 = part1.split('"></a>')[0];
var part3 = part2.split('<a title="').pop()
return part3
}
<div id="abc"> after the processing , you will get the answer </div>
You can check this answer :
your issue was : "But I don't know what should do to return pieces of the text, it's returning whole html."
lets assunme your html file is :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="abcd"> <a title="Hello World"></a></div>
<div > test 2 </div>
<div > test 3 </div>
</body>
</html>
now you will get the whole html as your response . and you want to parse the HTMl text and want to get the tag title "Hello World":
I make a custom function to parse the input HTML. now I have no idea about your HTML file.
please check the find_id_details() function .
in your code , at the place of console.log(template) , use console.log(find_id_details (template))
fetch('https://example.com/something')
.then(function (response) {
switch (response.status) {
// status "OK"
case 200:
return response.text();
// status "Not Found"
case 404:
throw response;
}
})
.then(function (template) {
console.log(find_id_details (template))
})
.catch(function (response) {
// "Not Found"
console.log(response.statusText);
});
function find_id_details (input){
var part1 = input.split('<div id="abcd">')[1];
var part2 = part1.split('"></a>')[0];
var part3 = part2.split('<a title="').pop()
return part3
}
This should do it:
fetch('https://github.com/')
.then(res => res.text())
.then(body => console.log(body));
Taken from node-fetch documentation https://www.npmjs.com/package/node-fetch
Or if you want to specifically get the title tag, you may use:
var titleTag = body.split('<title>')[1].split('</title>')[0];
if you want to manipulate string HTML, you have first convert it to HTML object (or parse the string). You can do it this way:
var htmlString = '<div class="test"><a title="Hello World"></a></div>';
var temp = document.createElement('div');
temp.innerHTML = htmlString;
var htmlObject = temp.firstChild;
console.log(htmlObject.getElementsByTagName("a")[0].getAttribute("title"))
//Get attribute from all elements by tag
var text = '<div class="test"><a title="Hello World"><a title="Hello Street"></a></a><a title="Hello City"></a></div>';
function getAttributeFromAllElementsByTag(htmlString, tag, attribute){
var tempArray = [];
var temp = document.createElement('div');
temp.innerHTML = htmlString;
var htmlObject = temp.firstChild;
var arrayOfElements = htmlObject.getElementsByTagName(tag);
for(var i = 0;i < arrayOfElements.length;i++){
tempArray.push(arrayOfElements[i].getAttribute(attribute))
}
return tempArray
}
console.log(getAttributeFromAllElementsByTag(text, "a", "title"))

Store value in a variable with Javascript

I'm a JS novice so be gentle.
I am working on a simple script that reads a value from another web page on my local Intranet.
Intranet Home Page (index.php):
<div id="username">my.username</div>
script.js:
$(document.body).load('http://intranet/index.php #username');
Now, I was wondering, instead of just displaying this value, how do I store it in a variable?
You want to query it with ajax, then parse that HTML, then find that element in the parsed HTML and extract its text:
$.ajax({
url: 'http://intranet/index.php',
success: function(html) {
var nodes = $.parseHTML(html);
var username = $("<div>").append(nodes).find("#username").text();
console.log(username);
}
});
Here's an example of the parsing/finding part using a static HTML string:
var html = '<html><body><div>foo<div id="username">my.username</div></div></body></html>';
var nodes = $.parseHTML(html);
var username = $("<div>").append(nodes).find("#username").text();
console.log(username);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Or without the wrapper div:
// Test finding it nested
test('<html><body><div>foo<div id="username">my.username</div></div></body></html>');
// Test finding it top-level
test('<div>foo</div><div id="username">my.username</div><div>bar</div>');
function test(html) {
var username = null;
$.parseHTML(html).some(function(node) {
if (node.id === "username") {
username = $(node).text();
return true;
}
node = $(node).find("#username");
if (node[0]) {
username = node.text();
return true;
}
});
console.log(username);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can see why I used the wrapper div. :-)

Get a source code from URL web page with JavaScript using JSONP

I'm trying to get the source code form a URL web page using JSONP.
This is the code:
<script type="text/javascript">
var your_url = '';
$(document).ready(function(){
jQuery.ajax = (function(_ajax){
var protocol = location.protocol,
hostname = location.hostname,
exRegex = RegExp(protocol + '//' + hostname),
YQL = 'http' + (/^https/.test(protocol)?'s':'') + '://query.yahooapis.com/v1/public/yql?callback=?',
query = 'select * from html where url="{URL}" and xpath="*"';
function isExternal(url) {
return !exRegex.test(url) && /:\/\//.test(url);
}
return function(o) {
var url = o.url;
if ( /get/i.test(o.type) && !/json/i.test(o.dataType) && isExternal(url) ) {
// Manipulate options so that JSONP-x request is made to YQL
o.url = YQL;
o.dataType = 'json';
o.data = {
q: query.replace(
'{URL}',
url + (o.data ?
(/\?/.test(url) ? '&' : '?') + jQuery.param(o.data)
: '')
),
format: 'xml'
};
// Since it's a JSONP request
// complete === success
if (!o.success && o.complete) {
o.success = o.complete;
delete o.complete;
}
o.success = (function(_success){
return function(data) {
if (_success) {
// Fake XHR callback.
_success.call(this, {
responseText: data.results[0]
// YQL screws with <script>s
// Get rid of them
.replace(/<script[^>]+?\/>|<script(.|\s)*?\/script>/gi, '')
}, 'success');
}
};
})(o.success);
}
return _ajax.apply(this, arguments);
};
})(jQuery.ajax);
$.ajax({
url: your_url,
type: 'GET',
success: function(res) {
var text = res.responseText;
//document.getElementById("contenuto").innerHTML = text;
alert(text);
}
});
});
</script>
I printed with an alert all the source code, from the URL.
alert(text);
First, how to know if the printed code is all the web code of the page?
If I try to do in this way
document.getElementById("contenuto").innerHTML = text;
this is the result:
\ \ <'+'/ins>\ \ \ '); } ]]>
I tried to use HTML DOM to print just one element, doing in this way
document.getElementById("contenuto").innerHTML = text;
var elem = text.getElementById("strip_adv").innerHTML;
document.getElementById("contenuto_1").innerHTML = elem;
}
But this is the error on the JS console:
text.getElementById is not a function
Recap:
I would to get the source code of a web page from URL, using JSONP.
I would use HTML DOM from the returned text, to keep only the element/class I need. I'm a newbie on JS, I'm trying to learn more & more about JS.
getElementById() is present only in the document object. What you are trying to do is trying to access getElementId from a string object.
Instead what I would suggest is insert the returned html string inside iframe and you can access the elements within iframe otherwise you can use some kind of html parser in your application.
lets say your html looks like this after you insert your html string inside iframe
<body>
<iframe id="one">
<html>
<body> <h1 id="strip_adv">Heading</h1> </body>
</html
</iframe>
</body>
function iframeObj( frameEle ) {
return frameEle.contentWindow
? frameEle.contentWindow.document
: frameEle.contentDocument
}
var element = iframeObj( document.getElementById('strip_adv') );

Temporarily unzip a file to view contents within a browser

I want to unzip a file that contains an html page, css, and js directories. I want to unzip this temporarily and view the html in an iFrame, preferrably. I am using jszip which is working. I got the html to load, but how do I add the image, js, and css folders into the iFrame?
Here is what I have so far...
<div id="jszip_utils"></div>
<iframe id="iframe"></iframe>
<script type="text/javascript">
function showError(elt, err) {
elt.innerHTML = "<p class='alert alert-danger'>" + err + "</p>";
}
function showContent(elt, content) {
elt.innerHTML = "<p class='alert alert-success'>loaded !<br/>" +
"Content = " + content + "</p>";
}
var htmltext = JSZipUtils.getBinaryContent("/zip/myWebsite.zip", function (err, data) {
var elt = document.getElementById('jszip_utils');
if (err) {
showError(elt, err);
return;
}
try {
JSZip.loadAsync(data)
.then(function (zip) {
for(var name in zip.files) {
if (name.substring(name.lastIndexOf('.') + 1) === "html") {
return zip.file(name).async("string");
}
}
return zip.file("").async("string");
})
.then(function success(text) {
$('#iframe').contents().find('html').html(text);
showContent(elt, text);
}, function error(e) {
showError(elt, e);
});
} catch(e) {
showError(elt, e);
}
});
</script>
This gets the html, but the js css and image files are not showing up. I believe I need to do some sort of fake routing, but I'm not sure how I would be able to do that. Thanks for your help.
If the html/js in the zip is not too complicated, for instance an AngularJS app that has routes for partials, this is possible.
The trick is to replace css,js,img src/href urls that point to a file in the zip with either:
Object Url: URL.createObjectURL(Blob or File object);
Data Url: data:[<mediatype>][;base64],<data>
Or in the case of js and css inject the content directly into the appropriate element
After replacing the src/href references than just inject the new html into the iframe.
Step 1: Parse the html so you can manipulate it
//html from a call like zip.file("index.html").async("string")
let parser = new DOMParser;
let doc = parser.parseFromString(html,"text/html");
Step 2: Find all elements with a relative path (e.g. /imgs/img.jpg) as they are easier to deal with as you can then use that path for zip.file
//Simply finds all resource elements, then filters all that dont start with '/'
var elements = jQuery("link[href],script[src],img[src]",doc).filter(function(){
return /^\//.test(this.href || this.src);
});
Step 3: Replace src,href with object url, data url, or direct content
//assume element is the html element: <script src="/js/main.js"></script>
zip.file(element.src).async("string").then(jsText=>{
element.src = "data:text/javascript,"+encodeURIComponent(jsText);
});
Step 4: Get the new html text and inject it into the iframe
let newHTML = doc.documentElement.outerHTML;
var viewer = document.querySelector('#iframeID');
viewer = viewer.contentWindow || viewer.contentDocument.document || viewer.contentDocument;
viewer.document.open();
viewer.document.write(html);
viewer.document.close();
JSFiddle Demo - Demonstrates replacing the src/href urls
As a security note, if you are using zip files that you do not know the contents of, you should run the whole app in a protected iframe

Categories

Resources