So i want to loop trough specific TD's in a LARGE html page. I'm using simplehtmldom in order to achieve that. The problem is that i cant make it work without putting every step in a foreach.
Here is my php
include('../inc/simple_html_dom.php');
$html = file_get_html("http://www.bjork-family.com/f43-london-stories");
// I just put the dom of pagebody into TEST
$test = $html->find('#page-body');
foreach($test->find('img') as $element)
{
echo "<img src='" . $element->src . "'/>" . '<br>';
}
i get this error
Fatal error: Call to a member function find() on array in /mywebsite.php on line 39
line 39 is this one
foreach($test->find('img') as $element)
I tried a lot of different things, if i keep it really really simple like that :
// Create DOM from URL or file
$html = file_get_html('http://www.bjork-family.com/f43-london-stories');
foreach($html->find('img') as $element)
echo $element->src . '<br>';
then it works !
So it seems to be working when i go like that
foreach($html->find('div') as $element)
{
if($element->id == 'page-body')
{
echo $element->id;
echo "EXIST <br>";
}
// echo "<img src='" . $element->src . "'/>" . '<br>';
}
But i don't want to search into my html only using foreach, is there another way where i can get to my position and then do i loop (i have to loop trough tr in a table )
$test = $html->find('#page-body');
Now $test is an array
$test = $html->find('#page-body', 0);
Now $test is an element
foreach($test->find('img') as $element)
{
echo "<img src='" . $element->src . "'/>" . '<br>';
}
This will work now. Also you can simplify with:
foreach($test->find('#page-body img') as $element)
{
echo "<img src='" . $element->src . "'/>" . '<br>';
}
Related
I need to create a CRON job that are weekly going to read a XML file. The XML file contains information about all the shows at a range of cinemas.
What I want to do is to read the XML file, extract the information I need about each show, and then upload each show to a database. But I run into trouble when I start nesting the for-loops.
I want each tuple to contain the following information:
Tile | FilmWebNr | Rating | Version | Center | Screen | Date | Time |
The URL for the XML is http://217.144.251.113/static/Shows_FilmWeb.php
Here is a pastebin where I try to list all the dates for each screen per Title.
Here is the result. As you can see, the dates is only displayed when there are more than 1 screen per Title. I dont get why the attributes array isn't always available.
I struggle with getting the last three (screen, date and time).
$map_url = "http://217.144.251.113/static/Shows_FilmWeb.php";
$response_xml_data = file_get_contents($map_url);
$data = simplexml_load_string($response_xml_data);
$array = (array) simplexml_load_string($response_xml_data);
$json = json_encode($array);
$configData = json_decode($json, true);
$movies = $configData['Performances']['Title'];
foreach ($movies as $title) {
echo "Title: " . $title['#attributes']['Name'] . '<br/>';
echo "FilmWebNr: " . $title['FilmWebNum'] . '<br/>';
echo "Rating: " . $title['TitleRating'] . '<br/>';
echo "Version: " . $title['TitleVersion'] . '<br/>';
echo "Center: " . $title['Center']['#attributes']['Name'] . '<br/>';
foreach ($title['Center']['Screen'] as $screen) {
//here I run into trouble
}
}
Let say I try to add the following in the inner loop:
$screen['#attributes']['Name'];
I get an error saying "Undefined index: #attributes".
So sometimes the attributes seems to be in an array, but sometimes not. Even though It is always a part of the XML.
Rather than going from XML-JSON-Arrays, it may be better to learn how to work with SimpleXML and you will find it's quite easy.
The main thing is to get used to how the various elements are layered and use foreach loops to iterate over the blocks...
$map_url = "http://217.144.251.113/static/Shows_FilmWeb.php";
$response_xml_data = file_get_contents($map_url);
$data = simplexml_load_string($response_xml_data);
$movies = $data->Performances->Title;
foreach ($movies as $title) {
echo "Title: " . $title['Name'] . '<br/>';
echo "FilmWebNr: " . $title->FilmWebNum . '<br/>';
echo "Rating: " . $title->TitleRating . '<br/>';
echo "Version: " . $title->TitleVersion . '<br/>';
echo "Center: " . $title->Center['Name'] . '<br/>';
foreach ($title->Center->Screen as $screen) {
echo "screen:".$screen['Name']. '<br/>';
foreach ( $screen->Date as $date ) {
echo "Date:".$date['Name']. '<br/>';
foreach ( $date->ShowID as $showID ) {
echo "Time:".$showID->Time. '<br/>';
}
}
}
}
I'm using PHPQuery to read some content from HTML, I'm unable to get the element by it's index using the square bracket notation.
See this simple example:
$html = '<div><table id="theTable"><tr><td>FIRST TD</td><td>SECOND TD</td><td>THIRD TD</td></tr></table></div>';
$pq = phpQuery::newDocumentHTML($html);
$table = $pq->find('#theTable');
$tds = $table->find('td');
echo "GETTING BY INDEX:\n\n";
echo '$tds[1] = ' . $tds[1];
echo "\n\n\n";
echo "GETTING IN FOREACH:\n\n";
foreach($tds as $key => $td){
echo '$tds[' . $key . '] = ' . pq($td) . "\n";
}
The output of this is:
GETTING BY INDEX:
$tds[1] =
GETTING IN FOREACH:
$tds[0] = FIRST TD
$tds[1] = SECOND TD
$tds[2] = THIRD TD
I would have expected that I can get the contents of $tds[1] using square brackets, but seems not. How can I get it by index?
Try a var_dump($tds), it'll tell you whats exactly inside the tds. Maybe those keys are actually strings and you should use:
echo "GETTING BY INDEX:\n\n";
echo '$tds['1'] = ' . $tds['1'];
Edit: Also, on your foreach you're using pq(), maybe you should use this
echo "GETTING BY INDEX:\n\n";
echo '$tds[1] = ' . pq($tds[1]);
Found the answer just after posting the question. Instead of square brackets you need to use eq(n):
echo '$tds[1] = ' . $tds->eq(1);
Try the following:
echo '$tds[1] = ' . $tds['1'];
Using PHP Simple HTML DOM Parse but unable to get images to display.
I am not a coder and am trying to pull articles and images from a website. The articles are fine but the images are not displaying. Instead part of the path displays e.g.
> //ssl.gstatic.com/ui/v1/button/search-white.png
> //ssl.gstatic.com/ui/v1/button/search-white.png
> //ssl.gstatic.com/ui/v1/icons/common/settings.png
Using Google as an example, here's the code I am using:
<?php
$html = file_get_html('https://news.google.com/nwshp?hl=en&tab=in');
foreach($html->find('h2') as $e)
echo $e->innertext . '<br><br>';
foreach($html->find('div.jsdisplay') as $e)
echo $e->innertext . '<br>';
foreach($html->find('img') as $element)
echo $element->src . '<br>';
?>
Thanks for any help
You should replace
foreach($html->find('img') as $element)
echo $element->src . '<br>';
With
foreach ( $html->find('img') as $element ) {
$img = str_replace(array("//ssl"), array("http://ssl"), $element->src);
for($i = 0; $i < 5; $i ++) {
$img = str_replace("//nt$i", "http://nt$i",$img);
}
echo "<img src=\"$img\" /> <br>";
}
Update my answer after your last comment with your original site URL 'http://frielatvsales.com/QuadAttachments.htm'
try below code.
include_once "simplehtmldom/simple_html_dom.php";
$url = "http://frielatvsales.com/QuadAttachments.htm";
$html = file_get_html($url);
preg_match('#^(?:http://)?([^/]+)#i', $url, $matches);
$host = $matches[1];
foreach($html->find('h2') as $e) {
echo $e->innertext . '<br><br>';
}
foreach($html->find('div.jsdisplay') as $e) {
echo $e->innertext . '<br>';
}
foreach($html->find('img') as $element) {
echo '<img src=http://'.$host.'/'.$element->src . ' /><br>';
}
//ssl.gstatic.com/ui/v1/button/search-white.png is a relative URI (the scheme is not specified, so it will use the same scheme (e.g. http: or https:) as the page it appears in).
Resolve it as you would any other relative URI.
My question is how to get the images to display using the code in my original post.
You have to output an <img> tag instead of the URI as plain text.
I've this code
$xml = simplexml_load_file("http://api.hostip.info/?ip=12.215.42.19");
echo $xml->getName() . "<br />";
foreach($xml->children() as $child) {
echo $child->getName() . ": " . $child . "<br />";
}
If I visit http://api.hostip.info/?ip=12.215.42.19 directly on the browser, I can see the XML return but when I tried the above code, only HostipLookupResultSet<br /> gets echoed.
How do I retrieve the data from this xml? I'm interested in getting coutry and country abbreviation.
I was trying something like echo $xml->HostipLookupResultSet->gml:featureMember->Hostip->countryName but it seems it is wrong.
This might work if you query using xpath :-
// optional for register namespace into xpath
$xml->registerXPathNamespace('gml', 'http://www.opengis.net/gml');
$result = $xml->xpath('//*[self::countryName or self::countryAbbrev]');
You need to add the namespace.
See the code bellow
/* #var $xml SimpleXMLElement */
echo $xml->getName() . "\n";
$namespaces = $xml->getDocNamespaces();
foreach($xml->children($namespaces['gml']) as $child) {
echo $child->getName() . ": " . $child . "\n";
}
You can try the following code for getting Country and Country Abbrevation:
$xml = simplexml_load_file("http://api.hostip.info/?ip=12.215.42.19");
$cntry= $xml->xpath('//gml:featureMember');
foreach($cntry as $child) {
echo $child->Hostip->countryName;
echo "<br />";
echo $child->Hostip->countryAbbrev;
}
foreach ($data['tests'] as $testname => $tests) {
echo "<h1>Extraction $testname Tests</h1>\n";
$function = $testfunctions[$testname];
echo "<ul>";
foreach ($tests as $test) {
echo "<li>" . $test['description'] . ' ... ';
$extracted = $extractor->$function($test['text']);
if ($test['expected'] == $extracted) {
echo " <span style='color: green'>passed.</span></li>";
} else {
echo " <span style='color: red'>failed.</span>";
echo "<pre>Original: " . htmlspecialchars($test['text']) . "\nExpected: " . print_r($test['expected'], true) . "\nActual : " . print_r($extracted, true) . "</pre>";
}
echo "</li>";
}
echo "</ul>";}
I keep getting the error:
Warning: Invalid argument supplied for
foreach() in
C:\xampp\htdocs\test\runtests.php on
line 49
p.s. the beginning of the code is line 49, so the probelm starts with the foreach statment.
Whenever i see that, it tends to mean that the thing i'm trying to iterate through isn't an array.
Check $data['tests'] (and each inner $tests) to make sure it's not null/unset/empty, and that it's something iterable like an array. Also keep in mind that older versions of PHP (before 5.0?) don't do iterable objects very well.
One of the elements in $data["tests"] is probably not an array.
Add this before the foreach:
if (is_array($tests))
foreach ($tests as $test) {...