I'm new to php simple_html_dom.php
I'm trying parse a small html page. But I'm getting an error.
Fatal error: Call to a member function find() on a non-object in C:\xampp\htdocs\result\do.php on line 8
My php code is here :
`
$html = new simple_html_dom();
$html->load_file('C:\xampp\htdocs\result\www.html');
$tableData = array();
$table = $html->find('table');
foreach($table->find('tr') as $row) {
$rowData = array();
foreach($row->find('td.text') as $cell) {
$rowData[] = $cell->innertext;
}
$tableData[] = $rowData;
}
echo "Result :<br/>";
foreach($tableData as $test)
echo "-".$test[0]."-".$test[1]."-".$test[2]."-".$test[3]."-".$test[4]."<br/>";
?>`
and my html page is here (www.html):
<table>
<tr>
<td width=250>Subject</td>
<td width=60 align=center>External </td>
<td width=60 align=center>Internal</td>
<td align=center width=60>Total</td>
<td align=center width=60>Result</td>
</tr>
<tr>
<td width=250><i>Analog Communication (06EC53)</i></td>
<td width=60 align=center>0</td>
<td width=60 align=center>17</td>
<td width=60 align=center>17</td>
<td width=60 align=center><b>A</b>
</td>
I want to know why I'm getting this error and how can I solve this error.
have you tried adding html and body tags around that ? I believe the library requires it.
it should be <html><body> .... </body></html>
That error means that you tried to call find() on something that was empty, probably because that something was the result of another call to find() that didn't actually find anything. The likely culprit here is $table because you never bother checking that $html->find('table') actually succeeds before going ahead and trying to use the result.
Related
The error states:
Fatal error: Cannot use object of type mysqli_result as array
Code:
$sqlselect=mysqli_query($connection_db, "SELECT * FROM chromebook WHERE chromebook.LokasiCb like '%".$LokasiCb."%'");
//Langkah#4: Bina table heading/ kepala jadual
echo "<center><table border='1'><tr>
<th>Bil</th>
<th>Kod Daftar</th>
<th>Nama Chrome Book</th>
<th>Lokasi Chrome Book</th>
<th>Padam</th>
</tr></center>";
$pembilang=1;
//Langkah#5: Mendapatkan data daripada pangkalan data dan memaparkan data dalam jadual
while($row=mysqli_fetch_array($sqlselect))
{
echo"<tr>
<td align='center'>".$pembilang."</td>
<td align='center'>".$row['KodDaftar']."</td>
<td align='center'>".$row['NamaCb']."</td>
<td align='center'>".$row['LokasiCb']."</td>
<td><a href='hapus.php?KodDaftar=$sqlselect[KodDaftar]&NamaCb&LokasiCb=$sqlselect[NamaCb]'>Padam</a></td>
</tr>";
$pembilang++; //menambah pembilang
}
echo"</table>";
}
What happens is that in your code you use
$sqlselect[KodDaftar] and this causes the problem $sqlselect in this case is actually a mysqli_result object not an associative array. Therefore, the error.
Change this line
<td align='center'>".$row['LokasiCb']."</td>
<td><a href='hapus.php?KodDaftar=$sqlselect[KodDaftar]&NamaCb&LokasiCb=$sqlselect[NamaCb]'>Padam</a></td>
</tr>";
to
<td align='center'>".$row['LokasiCb']."</td>
<td><a href='hapus.php?KodDaftar=".$row['KodDaftar']."&NamaCb&LokasiCb=".$row['NamaCb']."'>Padam</a></td>
</tr>";
That will solve the problem.
Within your link href, you have values like this:
$sqlselect[KodDaftar] and $sqlselect[NamaCb]
...which should be $row not $sqlselect.
The $sqlselect is your result set not your individual row.
I am really struggling attempting to scrape a table either via XPath or any sort of 'getElement' method. I have searched around and attempted various different approaches to solve my problem below but have come up short and really appreciate any help.
First, the HTML portion I am trying to scrape is the 2nd table on the document and looks like:
<table class="table2" border="1" cellspacing="0" cellpadding="3">
<tbody>
<tr><th colspan="8" align="left">Status Information</th></tr>
<tr><th align="left">Status</th><th align="left">Type</th><th align="left">Address</th><th align="left">LP</th><th align="left">Agent Info</th><th align="left">Agent Email</th><th align="left">Phone</th><th align="center">Email Tmplt</th></tr>
<tr></tr>
<tr>
<td align="left">Active</td>
<td align="left">Resale</td>
<td align="center">*Property Address*</td>
<td align="right">*Price*</td>
<td align="center">*Agent Info*</td>
<td align="center">*Agent Email*</td>
<td align="center">*Agent Phone*</td>
<td align="center"> </td>
</tr>
<tr>
<td align="left">Active</td>
<td align="left">Resale</td>
<td align="center">*Property Address*</td>
<td align="right">*Price*</td>
<td align="center">*Agent Info*</td>
<td align="center">*Agent Email*</td>
<td align="center">*Agent Phone*</td>
<td align="center"> </td>
</tr>
...etc
With additional trs continuing containing 8 tds with the same information as detailed above.
What I need to do is iterate through the trs and internal tds to pick up each piece of information (inside the td) for each entry (inside of the tr).
Here is the code I have been struggling with:
<?php
$payload = array(
'http'=>array(
'method'=>"POST",
'content'=>'key=value'
)
);
stream_context_set_default($payload);
$dom = new DOMDocument();
libxml_use_internal_errors(TRUE);
$dom->loadHTMLFile('website-scraping-from.com');
libxml_clear_errors();
foreach ($dom->getElementsByTagName('tr') as $row){
foreach($dom->$row->getElementsByTagName('td') as $node){
echo $node->textContent . "<br/>";
}
}
?>
This code is not returning nearly what I need and I am having a lot of trouble trying to figure out how to fix it, perhaps XPath is a better route to go to find the table / information I need, but I have come up empty with that method as well. Any information is much appreciated.
If it matters, my end goal is to be able to take the table data and dump it into a database if the first td has a value of "Active".
Can this be of any help?
$table = $dom->getElementsByTagName('table')->item(1);
foreach ($table->getElementsByTagName('tr') as $row){
$cells = $row->getElementsByTagName('td');
if ( $cells->item(0)->nodeValue == 'Active' ) {
foreach($cells as $node){
echo $node->nodeValue . "<br/>";
}
}
}
This will fetch the second table, and display the contents of the rows starting with a first cell "Active".
Edit: Here is a more extensive help:
$arr = array();
$table = $dom->getElementsByTagName('table')->item(1);
foreach ($table->getElementsByTagName('tr') as $row){
$cells = $row->getElementsByTagName('td');
if ( $cells->item(0)->nodeValue == 'Active' ) {
$obj = new stdClass;
$obj->type = $cells->item(1)->nodeValue;
$obj->address = $cells->item(2)->nodeValue;
$obj->price = $cells->item(3)->nodeValue;
$obj->agent = $cells->item(4)->nodeValue;
$obj->email = $cells->item(5)->nodeValue;
$obj->phone = $cells->item(6)->nodeValue;
array_push( $arr, $obj );
}
}
print_r( $arr );
I am working on a PHP Simple DOM Parser and i want a simple solution for my question
<tr>
<td class="one">1</td>
<td class="two">2</td>
<td class="three">3</td>
</tr>
<tr>
<td class="one">10</td>
<td class="two">20</td>
<td class="three">30</td>
</tr>...
the html of mine is will look similar to the above
and i am looping over through td something like this
foreach ($sample->find("td") as $ele)
{
if($ele->class == "one")
echo "ONE = ".$ele->plaintext;
if($ele->class == "two")
echo "TWO= ".$ele->plaintext;
}
But is there any simple solution that without if condition getting the plaintext of particular class i dont want shorthand if also
I am expecting something like this below
$ele->class->one
take a look at it:
<?php
$html = "
<table>
<tr>
<td class='one'>1</td>
<td class='two'>2</td>
<td class='three'>3</td>
</tr>
<tr>
<td class='one'>10</td>
<td class='two'>20</td>
<td class='three'>30</td>
</tr>
</table>
";
// Your class name
$classeName = 'one';
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
// Get the results
$results = $xpath->query("//*[#class='" . $classeName . "']");
for($i=0; $i < $results->length; $i++) {
echo $review = $results->item($i)->nodeValue . "<br>";
}
?>
As you may know, Joomla components enable you to override their output by copying their template files into your site template. Joomla components generally use helper files which cannot be overridden.
I have a helper.php file that includes the string:
$specific_fields_text = '<tr><td class="key">'.$specific_field_title.': </td><td class="kr_sidecol_subaddress">'.$specific_fields[$i]->text.' '.$specific_fields[$i]->description.'</td></tr>';
In my template override is the code:
<table border="0" cellpadding="2" cellspacing="0">
<?php echo koparentHTML::getHTMLSpecificFields($this->specific_fields); ?>
</table>
The output is as follows:
<table border="0" cellpadding="2" cellspacing="0">
<tr>
<td class="key">title</td>
<td class="kr_sidecol_subaddress">value</td>
</tr>
<tr>
<td class="key">title</td>
<td class="kr_sidecol_subaddress">value</td>
</tr>
//.....etc......//
</table>
Basically I want to get rid of the table and turn it into a definition list but I cannot modify the helper.php file. I am thinking that the answer is to do with str_replace
I have tried using:
<dl>
<?php
$spec_fields = koparentHTML::getHTMLSpecificFields($this->specific_fields);
$spec_fields_dl = str_replace("<tr><td class='key'>'.$specific_field_title.': </td><td class='kr_sidecol_subaddress'>'.$specific_fields[$i]->text.' '.$specific_fields[$i]->description.'</td></tr>'", "<dt class='key'>'.$specific_field_title.': </dt><dd class='kr_sidecol_subaddress'>'.$specific_fields[$i]->text.' '.$specific_fields[$i]->description.'</dd>'", $spec_fields);
echo $spec_fields_dl;
?>
</dl>
This returns all of the text but with no html tags (no tr, td, dt, etc).
You can easily parse table data with PHP, like in this example:
$doc = new DOMDocument();
$doc->loadHTML(koparentHTML::getHTMLSpecificFields($this->specific_fields));
$rows = $doc->getElementsByTagName('tr');
$data = array();
for ($i = 0; $i < $rows->length; $i++) {
$cols = $rows->item($i)->getElementsbyTagName("td");
$data[$cols->item(0)->nodeValue] = $data[$cols->item(1)->nodeValue];
}
var_dump $data;
This should convert your table into assoc array ('title' => 'value').
I hope it helps.
I have figured this out. For some reason the PHP bits such as '.$specific_field_title.' where stopping the str_replace from working. To get around this I just searched for the HTML elements and put them in an array like so:
echo str_replace(array('<tr><td class="key">', '</td><td class="kr_sidecol_subaddress">', '</td></tr>'),
array('<dt class="key">', '</dt><dd class="kr_sidecol_subaddress">', '</dd>'),
koparentHTML::getHTMLSpecificFields($this->specific_fields));
And now this works perfectly. Thank you to everyone who contributed.
I'm trying to use if-statement to change <td>-s color.
Basically, I have a simple query to retrieve information from the database.
Additionaly, I have a column there which keeps the information like if the task is accomplished or not. When I retrieve the information I get all of them, but I need the accomplished tasks to be green, and others without any color.
I've searhed for the answer, but I couldn't find anything that satisfies me.
For example:
$qry = mysql_query("select * from table");
$recs = array();
while($row = mysql_fetch_array($qry))
$recs[]=$row;
mysql_free_result($qry);
I've tried to add while statement to the code above, but I was confused and it didnt work :(
I'm printing the results using heredoc:
How to give them color here?
<?php
$last_id=0;
foreach($recs as $rec)
{
$html=<<<HTML
<tr>
<td><b>Номер</b></td>
<td>$rec[0]</td>
</tr>
<tr>
<td><b>Номер документа</b></td>
<td>$rec[1]</td>
</tr>
<tr>
<td><b>Дата регистрации</b></td>
<td>$rec[8]</td>
</tr>
<tr>
<td><b>От кого</b></td>
<td>$rec[2]</td>
</tr>
<tr>
<td><b>По</b></td>
<td>$rec[4]</td>
</tr>
<tr>
<td><b>Краткое содержание</b></td>
<td>$rec[3]</td>
</tr>
<tr>
<td><b>Исполнитель</b></td>
<td>$rec[5]</td>
</tr>
<tr>
<td><b>Срок исполнения</b></td>
<td>$rec[6]</td>
</tr>
<tr>
<td><b>Срок исполнения продлен до</b></td>
<td><b>$rec[10]</b></td>
</tr>
<tr>
<td><b>Прислан</b></td>
<td>$rec[9]</td>
</tr>
<tr>
<td><b>Примечание</b></td>
<td>$rec[7]</td>
</tr>
<tr>
<td bgcolor="#838B83"> </td>
<td bgcolor="#838B83"> </td>
</tr>
HTML;
print $html;
if($rec[0]>$last_id)
$last_id=$rec[0];
};
$new_id=$last_id+1;
?>
rather than colour use a class, so you can change it in CSS
<td<?php if($row['complete']) echo ' class="complete"'; ?>>data</td>
<table>
<tr>
<td>column heading</td>
</tr>
<?php
$qry=mysql_query("select * from table");
while($row=mysql_fetch_array($qry)) {
if($row['urcolumnn']==1)
{
echo "<tr bgcolor=green>";
}
else
{
echo "<tr>";
}
?>
<td>
<?php echo $row['urcolumn']; ?>
</td>
</tr>
<?php } ?>
</table>
This is an example code. think this will help you. here i give the background color to <tr> like this if u want to give color to <td> use this <td style="background-color:green;">
I would suggest you to use ternary operator, rather than using IF statement, or your could use another workaround to use arrays to define colors, this would help you to define various colors for each status value globally, please find an example below:
$aryColor = array(
'complete' => 'green',
'incomplete' => "red",
'pending' => 'orange'
.....
);
//you can specify values for all of your status, or leave them blank for no color, the keys in the array are the possible values from your status field
foreach($recs as $rec) {
echo '<tr bgcolor="'.$aryColor[$rec['status_field']].'">
<td>'.$rec['title_field'].'</td>
</tr>';
}
I hope this helps you out, and you can easily edit this for HEREDOC.
first you should change your column values change its structure to int and set default value as "0".so when your task is complete the field value should be change to "1".
now come to your code:
$qry = mysql_query("select * from table");
while($row = mysql_fetch_assoc($qry)){
if($row['status']==1){
echo "<td color="green">Data</td>"
}
else{
echo "<td color="white">Data</td>";
}
}
Hence you can get the rows in green which status is==1 means complete and white for incomplete.