I'm trying to extract the main table from a website, convert it to JSON, but the tables before the one I want are obstructing the code I'm using. The code I'm using:
<?php
$singles_chart_url = 'http://www.mediabase.com/mmrweb/allaboutcountry/Charts.asp?format=C1R';
// Get the mode from the user:
$mode = $_GET['chart'];
// This is an array of elements to remove from the content before stripping it:
$newlines = array("\t", "\n", "\r", "\x20\x20", "\0", "\x0B");
switch($mode)
{
// They want the Singles chart, or haven't specified what they want:
case 'singles':
case '':
default:
$content = file_get_contents($singles_chart_url);
$start_search = '<table width="100%" border="0" cellpadding="2" cellspacing="2">';
break;
}
$content = str_replace($newlines, "", html_entity_decode($content));
$scrape_start = strpos($content, $start_search);
$scrape_end = strpos($content, '</table>', $scrape_start);
$the_table = substr($content, $scrape_start, ($scrape_end - $scrape_start));
// Now loop through the rows and get the data we need:
preg_match_all("|<tr(.*)</tr>|U", $the_table, $rows);
// Set the heading so we can output nice XML:
switch($_REQUEST['format'])
{
case 'json':
default:
header('Content-type: application/json');
$count = 0;
foreach($rows[0] as $row)
{
// Check it's OK:
if(!strpos($row, '<th'))
{
// Get the cells:
preg_match_all("|<td(.*)</td>|U", $row, $cells);
$cells = $cells[0];
$position = strip_tags($cells[0]);
$plus = strip_tags($cells[1]);
$artist = strip_tags($cells[2]);
$weeks = strip_tags($cells[3]);
echo "\n\t\t" . '{';
echo "\n\t\t\t" . '"position" : "' . $position . '", ';
echo "\n\t\t\t" . '"plus" : "' . $plus . '", ';
echo "\n\t\t\t" . '"artist" : "' . $artist . '", ';
echo "\n\t\t\t" . '"noWeeks" : "' . $weeks . '" ';
echo ($count != (count($rows[0]) - 2)) ? "\n\t\t" . '}, ' : "\n\t\t" . '}';
$count++;
}
}
echo "\n\t" . ']';
echo "\n" . '}';
break;
}?>
The website I'm trying to scrape. The goal is to retrieve json results of the table beginning after LW, TW, Artist, Title, etc. The above returns:
{
"chartDate" : "",
"retrieved" : "1444101246",
"entries" :
[
{
"position" : "7 DayCharts",
"plus" : "Country Past 7 Days -by Overall Rank Return to Main Menu ",
"artist" : " ",
"noWeeks" : "",
"peak" : "",
"points" : "",
"increase" : "",
"us" : ""
},
]
}
instead of
{
"chartDate" : "",
"retrieved" : "1444101246",
"entries" :
[
{
"position" : "2",
"plus" : "1",
"artist" : "KENNY CHESNEY",
"noWeeks" : "Save It For A Rainy"", etc . etc.
},
]
}
What could I add to the code above to retrieve that table?
Update
The problem is the match pattern.
After following statement,
$content = str_replace($newlines, "", html_entity_decode($content));
Some characters are replace or removed, such as " and Some tags are being in UPPERCASE. Hence you are always getting 0 as strpos for $scrape_start no matter what $start_search contains.
So you have to search like,
$start_search ='<TBODY>';
Working code on PhpFiddle
Related
I'm toying with a small program that can pass a list of words to the Merriam-Webster API, and gets returned the definition, part of speech, sample sentence and so on.
The JSON string returned for each word by the API is as follows:
{
"meta": {
"id": "vase",
"uuid": "eb4f8388-84b2-4fd4-bfc8-2686a0222b73",
"src": "learners",
"section": "alpha",
"target": {
"tuuid": "60e7797e-fd75-43e1-a941-3def0963d822",
"tsrc": "collegiate"
},
"stems": [
"vase",
"vaselike",
"vases"
],
"app-shortdef": {
"hw": "vase",
"fl": "noun",
"def": ["{bc} a container that is used for holding flowers or for decoration"]
},
"offensive": false
},
"hwi": {
"hw": "vase",
"prs": [
{
"ipa": "ˈveɪs",
"pun": ",",
"sound": {"audio": "vase0002"}
},
{
"l": "British",
"ipa": "ˈvɑːz",
"sound": {"audio": "vase0003"}
}
]
},
"fl": "noun",
"ins": [
{
"il": "plural",
"if": "vas*es"
}
],
"gram": "count",
"def": [
{
"sseq": [
[
[
"sense",
{
"dt": [
[
"text",
"{bc}a container that is used for holding flowers or for decoration "
],
[
"vis",
[
{"t": "a beautiful Chinese {it}vase{/it}"},
{"t": "a {it}vase{/it} of roses"}
]
]
]
}
]
]
]
}
],
"shortdef": ["a container that is used for holding flowers or for decoration"]
}
]
The code I'm using to pull the information from the API is as follows:
<?php
$handle = fopen("inputfile.txt", "r");
if ($handle)
{
while (($line = fgets($handle)) !== false)
{
// process the line read.
//$json_new = grab_json_definition(trim($line), "collegiate", "0f3ee238-c219-472d-9079-df5ec8c0eb7d");
$json_new = grab_json_definition(trim($line) , "learners", "d300a82d-1f00-4f09-ac62-7ab37be796e8");
$data = json_decode($json_new, true);
echo "Word: " . $data[0]['meta']['id'] . "<br/>";
echo "IPA: " . $data[0]['hwi']['prs'][0][ipa] . "<br/>";
echo "Part of Speech: " . $data[0]['fl'] . "<br/>";
echo "Definition: " . $data[0]['shortdef'][0] . "<br/>";
echo "Sentence: " . $data[0]['def'][0]['sseq'][0][0][0] . "<br/>";
}
fclose($handle);
}
else
{
// error opening the file.
}
function grab_json_definition($word, $ref, $key)
{
$uri = "https://www.dictionaryapi.com/api/v3/references/" . urlencode($ref) . "/json/" . urlencode($word) . "?key=" . urlencode($key);
return file_get_contents($uri);
};
?>
I can easily navigate through to get the Word, Definition and so on, but I can't navigate down to "t" to get the sample sentences. I'm sure it's something basic but I can't figure it out. Any help would be appreciated.
First, your JSON example is broken, I believe it is missing a [ in the beginning.
Now, Here is an example, where I load the contents of the file, json_decode your SINGLE example. Note that I am not adding a foreach loop or while loop, but I am getting all of the attributes you are aiming for:
<?php
$f = file_get_contents('inputfile.txt');
$data = json_decode($f);
print_r($data);
echo "Word: " . $data[0]->meta->id . "<br/>";
echo "IPA: " . $data[0]->hwi->prs[0]->ipa . "<br/>";
echo "Part of Speech: " . $data[0]->fl . "<br/>";
echo "Definition: " . $data[0]->shortdef[0] . "<br/>";
echo "Sentence: " . $data[0]->def[0]->sseq[0][0][0] . "<br/>";
echo "T1: " . $data[0]->def[0]->sseq[0][0][1]->dt[1][1][0]->t . "<br/>"; // those can also be in foreach loop, I am just showing the basic example of accessing the attributes
echo "T2: " . $data[0]->def[0]->sseq[0][0][1]->dt[1][1][1]->t . "<br/>";
You can extend this code, or modify yours to add while/foreach loops... as you need them..
I'm attempting to make a button that, based on the selected form/inputs on the page, will bring you to a page called "typeDefine.php?openness=3?conscientiousness=2?extroversion=1?agreeableness=2?neuroticism=1"(the numbers varying based on the selected inputs). However, $selectedNum- the variable that would ideally be containing the $_POST for each input- is returning an error immediately once the page is loaded, saying:
Undefined index
<?php
$typeWords = array("openness", "conscientiousness", "extroversion", "agreeableness", "neuroticism");
$typeLetters = array("o", "c", "e", "a", "n");
$typePath = "";
$correspondingLetters = array("I", "II", "III");
$isFirst = true;
foreach($typeWords as $typeWord)
{
$selectedNum = $_POST[$typeWord];//error here!!!
if(isset($selectedNum))//if got $typeWord in a form
{
$separationChar;
if($isFirst)
{
$separationChar = "?";
$isFirst = false;
}
else
{
$separationChar = "&";
}
$typePath = $typePath . $separationChar . $typeWord . "=" . $selectedNum;//e.g. $typePath = "?openness=3?conscientiousness=2?extroversion=1?agreeableness=2?neuroticism=1" for $_GET method after arriving on next page
}
}
echo 'search for type
<div>';
foreach($typeWords as $typeWord)
{
$typeLetter = substr($typeWord, 0, 1);
echo '<form method = "post" class = "column">';
for($i = 1; $i <= 3; $i++)
{
echo '<input type = "radio" name = "' . $typeWord . '" id = "' . $typeLetter . $i . '"><label for = "' . $typeLetter . $i . '">' . $correspondingLetters[$i - 1] . '</label>';//sets each input name to $typeWord for $_POST above
}
echo '<li class = "textHighlight">' . $typeWord . '</li>
</form>';
}
echo '</div>';
?>
What can I do to fix this error, in turn filling $typePath and making the script correctly bring you to the desired url upon the button's click?
Thanks in advance!
You should perform the isset() test on the $_POST element, not the variable that you set from it.
foreach ($typeWords as $typeWord)
{
if (isset($_POST[$typeWord])) {
$selectedNum = $_POST[$typeWord];
$typePath = $typePath . "?" . $typeWord . "=" . $selectedNum;
}
}
Note that multiple parameters need to be separated with &, ? should only be used at the beginning. There's a built-in function that will create a query string from an array, you can use that:
$typeArray = [];
foreach ($typeWords as $typeWord)
{
if (isset($_POST[$typeWord])) {
$selectedNum = $_POST[$typeWord];
$typeArray[$typeWord] = $selectedNum;
}
}
$typePath = $typePath . "?" . http_build_query($typeArray);
You can also replace the loop with:
$typeArray = array_intersect_key($_POST, array_flip($typeWords));
You execute your code immidiately without a present $_POST array.
You have to wrap your post related code with an if statement like this:
if ($_POST) {
$selectedNum = $_POST[$typeWord];
}
I have a simple PHP of statement but it keeps giving me 'Internal 500'.
Can anyone see what is wrong with this code?
(It works without the 'if')
$fullyfiltered = preg_replace('/<span>(.*?)<\/span>/', '<div class="chat-message ' if('$1'=="MichaelD"){'me'}else{'chat-midnightblue'}'"><div class="chat-contact"><img src="/assets/demo/avatar/tswan.png" alt=""></div><div id="chat-text" class="chat-text">$1: ', $nearlyfiltered);
EDIT - Full script:
<script>
setInterval(function(){
document.getElementById('chat-text').innerHTML = '';
<?php
$fh = fopen('chat.txt','r');
while ($line = fgets($fh)) {
//echo "<p>" . $line . "</p>";
$filtered = str_replace("'", "\\'", $line);
$almostfiltered = str_replace("<span></span>\n", "", $filtered);
$nearlyfiltered = trim(preg_replace('/\s\s+/', ' ', $almostfiltered));
$fullyfiltered = preg_replace('/<span>(.*?)<\/span>/', '<div class="chat-message ' if('$one'=="MichaelD"){'me'}else{'chat-midnightblue'}'"><div class="chat-contact"><img src="/assets/demo/avatar/tswan.png" alt=""></div><div id="chat-text" class="chat-text">$1: ', $nearlyfiltered);
if(!empty($fullyfiltered)){
$endingp = "</div></div>';";
} else {
$endingp = "';";
}
echo "document.getElementById('chat-text').innerHTML = document.getElementById('chat-text').innerHTML + '" . $fullyfiltered . $endingp;
}
fclose($fh);
?>
},5000);
</script>
callback must be a function, not just random script parts. Please read the manual (http://php.net/manual/en/function.preg-replace-callback.php)
So, I want to create dynamic donut chart, where the datas are from mySql database. But, the problem is in that chart, the datas get from JSON.
My question, how to use datas from PHP to be use for JSON datas. here're my progress so far :
<?php
$query_A = "SELECT COUNT(category) as catg FROM mydata ORDER BY category";
$result_A = mysql_query($query_A);
$query_B = "SELECT COUNT(category) as catg FROM mydata ORDER BY category";
$result_B = mysql_query($query_B);
//Print JSON
$prefix = '';
"[\n";
while ( $row_A = mysql_fetch_assoc( $result_A ) ) {
$prefix . " {<br>";
' "category": "' . "A" . '",' . "<br>";
' "value": ' . $row_A['catg'] . ',' . "<br>";
" }";
$prefix = ",\n";
}
while ( $row_B = mysql_fetch_assoc( $result_B ) ) {
$prefix . " {<br>";
' "category": "' . "B" . '",' . "<br>";
' "value": ' . $row_B['catg'] . ',' . "<br>";
" }";
$prefix = ",\n";
}
"\n]";
?>
And here're JSON datas from that donut chart :
<script type="text/javascript">
var chart = AmCharts.makeChart( "chartdiv", {
"type": "pie",
"theme": "light",
"dataProvider": [ {
"title": "New",
"value": 200
}, {
"title": "Returning",
"value": 9899
}, {
"title": "Back",
"value": 900
} ],
"titleField": "title",
"valueField": "value",
"labelRadius": 10,
"radius": "42%",
"innerRadius": "60%",
"labelText": "[[title]]",
"export": {
"enabled": true
}
} );
</script>
I want to use my mysql datas for that JSON datas. Thank you
There's a handy function called json_encode. Simply run your data through this function.
$json = json_encode($data); // returns a JSON string
By the way, have you tried googling for "PHP create JSON" or something similar? The time it took you to write this question, you would already have found a solution. Not to mention the time you wasted on trying to create the JSON yourself.
Just saying, you can save a lot of time by asking a search engine … you are usually not the first to have a particular problem.
I can't understand why there are two identical queries but that said.
<?php
$query_A = "SELECT COUNT(`category`) as 'catg' FROM `mydata` ORDER BY `category`";
$result_A = mysql_query( $query_A );
$query_B = "SELECT COUNT(`category`) as 'catg' FROM `mydata` ORDER BY `category`";
$result_B = mysql_query( $query_B );
if( $result_A ){
$data=array();
while ( $row_A = mysql_fetch_assoc( $result_A ) ) {
$data[]=array('category'=>'A', 'value'=>$row_A['catg'] );
}
$json_A=json_encode( $data );
}
if( $result_B ){
$data=array();
while ( $row_B = mysql_fetch_assoc( $result_B ) ) {
$data[]=array('category'=>'B', 'value'=>$row_B['catg'] );
}
$json_B=json_encode( $data );
}
?>
Then, in your javascript you could do this:-
var json_a=<?php echo $json_A;?>;
var json_b=<?php echo $json_B;?>;
I have a loop of data that will only echo the loop inside the while function, but if i call/echo the looped data outside the while function, it only runs the 1st loop.
SAMPLE:
$num = mysql_num_rows($queryFromDB);
$i=0;
while($i < $num)
{
$field1= mysql_result($queryFromDB,$i,"field1");
$field2= mysql_result($queryFromDB,$i,"field2");
$bothFields = $field1 . " " . $field2 "\n";
// This will show 2 rows of data
echo $bothFields;
$i++;
// This will only show 1 row of data. How can I pass the looped data to another variable?
echo $bothFields;
}
The output that I wanted to show is:
TITLE/HEADER GOES HERE in the 1st Line
-1st Row of Data from DB
-2nd Row of Data from DB
Here's the actual code:
$num = mysql_num_rows($qWoundAssessment);
$i=0;
while ($i < $num)
{
$wndType = mysql_result($qWoundAssessment,$i,"wndType");
$wndNum = mysql_result($qWoundAssessment,$i,"wndNum");
$wndLocation = mysql_result($qWoundAssessment,$i,"wndLocation");
$wndStage = mysql_result($qWoundAssessment,$i,"wndStage");
$wndL = mysql_result($qWoundAssessment,$i,"wndL");
$wndD = mysql_result($qWoundAssessment,$i,"wndD");
$wndW = mysql_result($qWoundAssessment,$i,"wndW");
$wndAseptic = mysql_result($qWoundAssessment,$i,"wndAseptic");
$wndIrrigate = mysql_result($qWoundAssessment,$i,"wndIrrigate");
$wndIrrigateBox = mysql_result($qWoundAssessment,$i,"wndIrrigateBox");
$wndPat = mysql_result($qWoundAssessment,$i,"wndPat");
$wndCover = mysql_result($qWoundAssessment,$i,"wndCover");
$wndCoverBox = mysql_result($qWoundAssessment,$i,"wndCoverBox");
$wndSecure = mysql_result($qWoundAssessment,$i,"wndSecure");
$wndSecureBox = mysql_result($qWoundAssessment,$i,"wndSecureBox");
$wndQvisit = mysql_result($qWoundAssessment,$i,"wndQvisit");
$wnd = "-" . $wndType . " " . "#" . $wndNum . ", " . "LOCATION " . $wndLocation . ", " . "STAGE " . $wndStage;
$wndSize = "SIZE " . $wndL . "CM" . " X " . $wndW . "CM" . " X " . $wndD;
if($wndAseptic=="1"){$wndAsepticTech = "USING ASEPTIC TECHNIQUE";}
if($wndIrrigate=="1"){$wndIrrigateWith = "IRRIGATE WITH " . $wndIrrigateBox;}
if($wndPat=="1"){$wndPatDry = "PAT DRY";}
if($wndCover=="1"){$wndCoverWith = "COVER WITH " . $wndCoverBox;}
if($wndSecure=="1"){$wndSecureWith = "COVER WITH " . $wndSecureBox;}
if($wndQvisit=="1"){$wndQv = "Q VISIT";}
if(isset($wnd, $wndSize, $wndAsepticTech, $wndIrrigateWith, $wndPatDry, $wndCoverWith, $wndSecureWith, $wndQv)){
$woundCare = implode(", ",array($wnd, $wndSize, $wndAsepticTech, $wndIrrigateWith, $wndPatDry, $wndCoverWith, $wndSecureWith, $wndQv)) . "\n\n ";}
$wndCare .= $woundCare;
$i++;
}
$snWoundCare = "SN TO PROVIDE SKILLED NURSING VISITS FOR WOUND CARE:" . "\n" . $wndCare;
if I echo $wndCare, it shows the "Undefined variable" error with the actual looped data. But if I pass this variable to PDF, it works.
SN TO PROVIDE SKILLED NURSING VISITS FOR WOUND CARE:
-PRESSURE ULCER #1, LOCATION COCCYX, 3, SIZE 2.0CM X 1.5CM X 0.07, USING ASEPTIC TECHNIQUE, IRRIGATE WITH NORMAL SALINE, PAT DRY, COVER WITH AQUACEL AG, COVER WITH MEPILEX BORDER, Q VISIT
-SURGICAL WOUND #2, LOCATION (R) KNEE, , SIZE 29CM X 0CM X 0, USING ASEPTIC TECHNIQUE, IRRIGATE WITH NORMAL SALINE, PAT DRY, COVER WITH AQUACEL AG, COVER WITH MEPILEX BORDER, Q VISIT
================ CODE NOW WORKS!!! HERE's MY FINAL SOLUTION ======================
$num = mysql_num_rows($qWoundAssessment);
$i=0;
$storeMyData = array();
while($i < $num)
{
$wnd= "-" . mysql_result($qWoundAssessment,$i,"wndType") . " #" . mysql_result($qWoundAssessment,$i,"wndNum"). ", LOCATION " . mysql_result($qWoundAssessment,$i,"wndLocation") . ", STAGE " . mysql_result($qWoundAssessment,$i,"wndStage");
$wndSize = "SIZE " . mysql_result($qWoundAssessment,$i,"wndL") . "CM" . " X " . mysql_result($qWoundAssessment,$i,"wndW") . "CM" . " X " . mysql_result($qWoundAssessment,$i,"wndD") . "CM";
if(isset($rowWoundAssessment['wndAseptic'])){$wndAsepticTech = "USING ASEPTIC TECHNIQUE";}
if(isset($rowWoundAssessment['wndIrrigate'])){$wndIrrigateWith = "IRRIGATE WITH " . mysql_result($qWoundAssessment,$i,"wndIrrigateBox");}
if(isset($rowWoundAssessment['wndPat'])){$wndPatDry = "PAT DRY";}
if(isset($rowWoundAssessment['wndCover'])){$wndCoverWith = "COVER WITH " . mysql_result($qWoundAssessment,$i,"wndCoverBox");}
if(isset($rowWoundAssessment['wndSecure'])){$wndSecureWith = "SECURE WITH " . mysql_result($qWoundAssessment,$i,"wndSecureBox");}
if(isset($rowWoundAssessment['wndQvisit'])){$wndQvisit = "Q VISIT";}
$wndCare = implode (", ", array($wnd, $wndSize, $wndAsepticTech, $wndIrrigateWith, $wndPatDry, $wndCoverWith, $wndSecureWith, $wndQvisit)). "\n\n";
// This will show 2 rows of data
$storeMyData[] = $wndCare ; // store current data in array
$i++;
}
/* this will echo your storedData of loop */
foreach($storeMyData as $prevData)
/* or join the data using string concatenation /
$allFinalData2 = "";
/ this will echo your storedData of loop */
foreach($storeMyData as $prevData)
{
$allFinalData2 = $allFinalData2.$prevData ; // keep on concatenating
}
echo "SN TO PROVIDE SKILLED NURSING VISITS FOR WOUND CARE:" . "\n" . $allFinalData2;
thanks to DhruvPathak and Antonio Laguna! You guys are the best! Just made my day! jumps around the room
This should work:
<?php
$wndCare = '';
while ($row = mysql_fetch_assoc($qWoundAssessment)){
$wnd = '-'.$row['wndType'].' #'..$row['wndNum'].', LOCATION '.$row['wndLocation'].', STAGE '.$row['wndStage'];
$wndSize = 'SIZE '.$row['wndL'].'CM X '.$row['wndW'].'CM X '.$row['wndD'];
$wndAsepticTech = ($row['wndAseptic'] == 1) ? 'USING ASEPTIC TECHNIQUE' : '';
$wndIrrigateWith = ($row['wndIrrigate'] == 1) ? 'IRRIGATE WITH '.$row['wndIrrigateBox'] : '';
$wndPatDry = ($row['wndPat'] == 1) ? 'PAT DRY' : '';
$wndCoverWith = ($row['wndCover'] == 1) ? 'COVER WITH'.$row['wndCoverBox'] : '';
$wndSecureWith = ($row['wndSecure'] == 1) ? 'COVER WITH'.$row['wndSecureBox'] : '';
$wndSecureWith = ($row['wndSecure'] == 1) ? 'COVER WITH'.$row['wndSecureBox'] : '';
$wndQvisit = ($row['wndQvisit'] == 1) ? 'Q VISIT' : '';
$wndCare .= implode (", ", array($wnd, $wndSize, $wndAsepticTech, $wndIrrigateWith, $wndPatDry, $wndCoverWith, $wndSecureWith, $wndQv)). '\n\n';
}
$snWoundCare = "SN TO PROVIDE SKILLED NURSING VISITS FOR WOUND CARE:" . "\n" . $wndCare;
?>
The issue I see is that you were testing if all variables where previously setted and this could make strange things as you were stablishing them sometimes and sometimes don't.
I am not sure what you want to do with your data. It seems you want to store
all the data to use it outside the loop, then this is the way to go :
<?php
$num = mysql_num_rows($queryFromDB);
$i=0;
$storeMyData = array();
while($i < $num)
{
$field1= mysql_result($queryFromDB,$i,"field1");
$field2= mysql_result($queryFromDB,$i,"field2");
$bothFields = $field1 . " " . $field2 "\n";
// This will show 2 rows of data
echo $bothFields;
$storeMyData[] = $bothFields ; // store current data in array
$i++;
}
/* this will echo your storedData of loop */
foreach($storeMyData as $prevData)
{
echo $prevData."\n";
}
?>
$allFinalData = implode("",$prevData); // implode will join all the data as string
echo $allFinalData."\n" ;
/* or join the data using string concatenation */
$allFinalData2 = "";
/* this will echo your storedData of loop */
foreach($storeMyData as $prevData)
{
$allFinalData2 = $allFinalData2.$prevData ; // keep on concatenating
}
echo $allFinalData2,"\n";
?>