XPath extract attribute from <div> in PHP - php

i want to extract an attribute from an and display its value.
<div class="b-text-4xl b-text-btc-first b-font-bold btcecc-animated liveup livedown" data-price="38696.15125182" data-live-price="bitcoin" data-rate="1" data-currency="USD" data-timeout="1610051644181"><span>38,696.15</span> <b class="fiat-symbol">$</b></div>
I need the value of "data-price".
The location of the full html is at https://www.btc-echo.de/kurs/bitcoin/
I tried this:
$url = "https://www.btc-echo.de/kurs/bitcoin/";
libxml_use_internal_errors(true);
$doc = new DOMDocument;
$doc->loadHTML(utf8_encode(file_get_contents($url)));
$xpath = new DOMXpath($doc);
foreach ($xpath->query('*[#id="main"]/div[1]/div[3]/div[2]/div[1]/div/div/div[1]/div/#data-price') as $textNode) {
echo $textNode->nodeValue;
}

Related

How to Get value with name by Dom

Hy friends I am using this method to get all href links from tag from a site
$DOM = new DOMDocument();
#$DOM->loadHTML($data);
#$links = $DOM->getElementsByTagName('a');
foreach($links as $link){
$url = $link->getAttribute('href');
echo $url;
Now I don't know how to get the value by name fb_dtsg ..... Here is the source code
<input type="hidden" name="fb_dtsg" value="AQF0dSiG6Lyr:AQEnJP0PhWzy" autocomplete="off" />
I want to get it's value with DOm how to do this...... Thanks in advance
$DOM = new DOMDocument();
#$DOM->loadHTML($data);
#$links = $DOM->getElementsByTagName('input');
foreach($inputs as $input) {
if ($input->getAttribute('name') == 'fb_dtsg') {
echo 'found, do whatever';
break;
}
}
You can use DOMXpath()'s query method to get elements by the name attribute.
$DOM = new DOMDocument();
#$DOM->loadHTML($data);
#$links = $DOM->getElementsByTagName('a');
$xpath = new DOMXpath($DOM);
$input = $xpath->query('//input[#name="fb_dtsg"]');
echo $input[0]->getAttribute('value');
This will print the value of the first input element with name 'fb_dtsg'.
Hope it helps :) Feel free to ask if you need to know anything more.
Use xpath for that.
$DOM = new DOMDocument();
#$DOM->loadHTML($data);
$xpath = new DOMXpath($DOM);
$elementByName = $xpath->query("//input[#name='fb_dtsg']");
...
http://php.net/manual/ro/class.domxpath.php
$DOM->getElementsByTagName('a'); // for tag name
$DOM->getElementsByName('fb_dtsg'); // for name
document.getElementById('fb_dtsg_id').value // for showing value of the field

How can I add an element into the middle of a text node's text?

Given the following HTML:
$content = '<html>
<body>
<div>
<p>During the interim there shall be nourishment supplied</p>
</div>
</body>
</html>';
How can I alter it to the following HTML:
<html>
<body>
<div>
<p>During the <span>interim</span> there shall be nourishment supplied</p>
</div>
</body>
</html>
I need to do this using DomDocument. Here's what I've tried:
$dom = new DomDocument();
$dom->loadHTML($content);
$dom->preserveWhiteSpace = false;
$xpath = new DOMXpath($dom);
$elements = $xpath->query("//*[contains(text(),'interim')]");
if (!is_null($elements)) {
foreach ($elements as $element) {
$text = $element->nodeValue;
$element->nodeValue = str_replace('interim','<span>interim</span>',$text);
}
}
echo $dom->saveHTML();
However, this outputs literal html entities so it renders like this in the browser:
During the <span>interim</span> there shall be nourishment supplied
I imagine one should use createElement and appendChild methods instead of assigning nodeValue directly but I can't see how to insert an element in the middle of a textNode string?
Marcus Harrison's answer using splitText is a good one, but it can be simplified and needs to use mb_* methods to work with UTF-8 input:
<?php
$html = <<<END
<html>
<meta charset="utf-8">
<body>
<div>
<p>During € the interim there shall be nourishment supplied</p>
</div>
</body>
</html>
END;
$replace = 'interim';
$doc = new DOMDocument;
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
$nodes = $xpath->query(sprintf('//text()[contains(., "%s")]', $replace));
foreach ($nodes as $node) {
$start = mb_strpos($node->textContent, $replace);
$end = $start + mb_strlen($replace);
$node->splitText($end); // do this first
$node->splitText($start); // do this last
$newnode = $doc->createElement('span');
$node->parentNode->insertBefore($newnode, $node->nextSibling);
$newnode->appendChild($newnode->nextSibling);
}
$doc->encoding = 'UTF-8';
print $doc->saveHTML($doc->documentElement);
Create a new DomDocument with modified element and replace the old one
foreach ($elements as $element) {
$text = $element->nodeValue;
$el = new DomDocument();
$el->loadHTML('<iframe>'. str_replace('interim','<span>interim</span>',$text) . '</iframe>');
$new = $dom->importNode($el->getElementsByTagName('iframe')->item(0), true);
unset($el);
$element->parentNode->replaceChild($new, $element);
}
In order to do this, you must use the DOMString's splitText interface. This accepts an offset, which can be retrieved by using strpos:
$dom = new DomDocument();
$dom->loadHTML($content);
$dom->preserveWhiteSpace = false;
$xpath = new DOMXpath($dom);
$elements = $xpath->query("//*[contains(text(),'interim')]");
if (!is_null($elements)) {
foreach ($elements as $element) {
$text = $element->childNodes->item(0);
$text->splitText(strpos($text->textContent, "interim"));
$text2 = $element->childNodes->item(1);
$text2->splitText(strpos($text2->textContent, " "));
$element->removeChild($text2);
$span = $dom->createElement("span");
$span->appendChild($dom->createTextNode("interim"));
$element->insertBefore($span, $element->childNodes->item(1));
}
}
echo $dom->saveHTML();
Edits: having just tested it, I realise I hadn't removed the original "interim" in the second text node. Edited this answer to do that. I have also edited this code to be as compatible with old versions of PHP as I can think of making it: as I don't run an old version of PHP it isn't possible for me to test that.

DomDocument/DOMXPath - How to get HTML Dom element by itemprop and img src

I am working on a script which is getting data from HTML DOM elements.
Here is my code:
$url = 'http://www.sportsdirect.com/nike-satire-mens-skate-shoes-242188?colcode=24218822';
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTMLFile($url);
$xpath = new DOMXpath($doc);
$Name = $xpath->query('//span[#id="ProductName"]')->item(0)->nodeValue;
echo $Name;
This code is simply taking the text inside <span id="ProductName"></span>. I know how to get the data from elements with specific class or id.
I don't know how I can get the src="http://adres-to-image.com/img.png" (pure example) from image tag or how I can get elements which do not have id or class but have attribute like itemprop, for example <div itemprop="name"></div>
How can I get the image src?
How can I get elements with itemprop?
For your examples:
$xpath->query('//img/#src)->item(0)->nodeValue
This means
Select all src attributes of all img tags and get the value of the first
$xpath->query('//div/[#itemprop="name"])->item(0)->nodeValue
This means
Select all divs with itemprop attr equals name and get the value of the first.
You just look for the attributes:
$url = 'http://www.sportsdirect.com/nike-satire-mens-skate-shoes-242188?colcode=24218822';
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTMLFile($url);
$xpath = new DOMXpath($doc);
$Name = $xpath->query('//div[#class="productImageSash"]');
foreach($Name as $element){
$imgs = $element->getElementsByTagName('img');
foreach($imgs as $img){
$src = $img->getAttribute('src');
echo $src;
}
}
Output:
/images/sash/productsash_mustgo.png
The same with itemprop attribute, look for divs which have this attribute:
$Name = $xpath->query('//div');
foreach($Name as $element){
$itemprop = $element->getAttribute('itemprop');
if($itemprop){
echo "found";
}
}

Iterate through elements with DOMDocument & DOMXPath

I am trying to iterate through every child element of the containing div:
$html = ' <div id="roothtml">
<h1>
Introduction</h1>
<p>text</p>
<h2>
text</h2>
<p>
test</p>
</div>';
And I have this PHP:
$dom = new DOMDocument();
$dom->loadHTML($html);
$dom->preserveWhitespace = false;
$xpath = new DOMXPath($dom);
$els = $xpath->query("/div");
print_r($els);
All I get though is DOMNodeList Object ( )
Having looked at the IBM tutorial I should be getting an array. What is it I am doing wrong?
Any help is appreciated.
You're using the wrong query string, you should be using //div.
Iterate over the list like this:
$els = $xpath->query("//div");
foreach( $els as $el) {
echo $el->textContent;
}

get value of <h2> of html page with PHP DOM?

I have a var of a HTTP (craigslist) link $link, and put the contents into $linkhtml. In this var is the HTML code for a craigslist page, $link.
I need to extract the text between <h2> and </h2>. I could use a regexp, but how do I do this with PHP DOM? I have this so far:
$linkhtml= file_get_contents($link);
$dom = new DOMDocument;
#$dom->loadHTML($linkhtml);
What do I do next to put the contents of the element <h2> into a var $title?
if DOMDocument looks complicated to understand/use to you, then you may try PHP Simple HTML DOM Parser which provides the easiest ever way to parse html.
require 'simple_html_dom.php';
$html = '<h1>Header 1</h1><h2>Header 2</h2>';
$dom = new simple_html_dom();
$dom->load( $html );
$title = $dom->find('h2',0)->plaintext;
echo $title; // outputs: Header 2
You can use this code:
$linkhtml= file_get_contents($link);
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($linkhtml); // loads your html
$xpath = new DOMXPath($doc);
$h2text = $xpath->evaluate("string(//h2/text())");
// $h2text is your text between <h2> and </h2>
You can do this with XPath: untested, may contain errors
$linkhtml= file_get_contents($link);
$dom = new DOMDocument;
#$dom->loadHTML($linkhtml);
$xpath = new DOMXpath($dom);
$elements = $xpath->query("/html/body/h2");
if (!is_null($elements)) {
foreach ($elements as $element) {
$nodes = $element->childNodes;
foreach ($nodes as $node) {
echo $node->nodeValue. "\n";
}
}
}

Categories