Php Web Crawler Click - javascript

<?php
include_once('simple_html_dom.php');
$veri = file_get_html("http://apps.istanbulsaglik.gov.tr/Eczane");
preg_match_all('#<a href="(.*?)" class="ilce-link" data-value="(.*?)"
data-ilcename="(.*?)" data-title="(.*?)" id="ilce" title="(.*?)"><i
class="fa fa-dot-circle-o"></i>(.*?)</a>#si',$veri,$baslik);
$length = count($baslik[4]);
for ($i = 0; $i < $length; $i++) {
echo $baslik[4][$i];
echo "</br>";
}
preg_match_all('#<table class="table ilce-nobet-detay" id="ilce-nobet-detay">(.*?)</table>#si',$veri,$adres);
echo $adres[1][1];
?>
In this link;
http://apps.istanbulsaglik.gov.tr/Eczane I can not get the right side elements that will be listed under "Eczaneler".
Because I need to click any of left side elements then, I can see them. What I want to do is getting that elements in my web crawler.
The main problem is how can I make my crawler click? without clicking I can not see any data.
If I can make it click, then I can take the data from html source. If not my crawler will always return empty.

If you use any browser's inspector on http://apps.istanbulsaglik.gov.tr/Eczane link, you will see that each link in İlçeler column has a data-value and binded to a click event:
the page Javascript code:
$(function () {
$(".ilce-link").on("click", function (parameters) {
var title = $(this).data("title").toUpperCase();
var id = $(this).data("value");
var request = $.ajax({
url: "/Eczane/nobetci",
method: "POST",
data: { "id": id, "token": "aa416735d12fd44b" },
dataType: "html"
});
request.done(function (data) {
$("#nobet").empty(" ");
$("#nobet").html('<i class="fa fa-spinner fa-spin"></i>');
$("#nobet").html(data);
document.title = "06-11-2017 TARİHİNDEKİ " + title + " İLEÇSİNDEKİ NÖBETÇİ ECZANE LİSTESİ";
});
});
});
This code means that when you click on any link in the left column, the script will create a post request by AJAX to this url: http://apps.istanbulsaglik.gov.tr/Eczane/nobetci with an id and a token.
So the idea is to directly use this url and post data, you can get the id from the link element and the token from the js code on the first page, and then use CURL PHP to post these data.
Here is an example using CURL post:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://apps.istanbulsaglik.gov.tr/Eczane/nobetci");
curl_setopt($ch, CURLOPT_POST, 1);
// you can use preg_match_all to retrieve the id and the token from the first page
curl_setopt($ch, CURLOPT_POSTFIELDS, "id=$id&token=$token");
$output = curl_exec ($ch);
curl_close ($ch);

Related

Get content of URL after the page has loaded

I need to fetch a string in a <div> from an URL. I'm using Ajax and PHP to retrieve the information. I've managed to collect the "correct" data.
The issue is, the data I'm collecting - which is a number -, is 0in the beginning and directly updates to 103 or some other random number once the page has fully loaded. I need the second one.
This is because the website I'm retrieving data from is made in ReactJS and updates that number dynamically with JSX.
I somehow need to get the data after the page has loaded all of it's content.
Long story short:
How can I fetch data from an URL after the page in question has loaded its full content by javascript?
My code:
/gethtml.php
function curl_get_file_contents($URL)
{
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($c, CURLOPT_URL, $URL);
$contents = curl_exec($c);
curl_close($c);
if ($contents) return $contents;
else return FALSE;
}
function get_number(){
$url = "https://www.example.com";
$html = curl_get_file_contents($url);
$dom = new DOMDocument;
#$dom->loadHTML($html);
$divs = $dom->getElementsByTagName('div');
$compare_string = "someClassName";
foreach ($divs as $div){
$c = $div->getAttribute("class");
if(strpos($c, $compare_string) !== false) {
return $c;
}
}
}
$num= get_number();
echo json_encode(array("value"=>$num));
Javascript / Ajax
jQuery(document).ready(function( $ ){
$.ajax({
url:"gethtml.php",
type: "post",
dataType: 'json',
data: {},
success:function(result){
console.log(result.value);
}
});
});
Visual example
Long story short: You should not manually update "views" that are controlled by React.
Even if you execute your code AFTER the page was initially rendered, there is the chance that the state of the component will change because of some reason and your change will be overwritten yet again.

PHP. saving many pages as png from the command line

I access a page via GET (some of its contents are loaded using jquery), on document.ready this page gets saved as a png.
I want to call this page from a command line using inside the command a for loop to save multiple pngs.
How can I do it?
If I run this on the browser it works fine but the idea is not to make it manually, one by one for each gln code.
curl did not work or am I using it wrong?
<script>
#isset($saveCode)
$("#btnPng").click();
#endisset
$("#btnPng").click(function () {
var selected_date = $('#selectReportDate').find(':selected').val() ;
var selected_gln = $('#selectAccount').find(':selected').val() ;
html2canvas($("#printable"), {
onrendered: function (canvas) {
var url = canvas.toDataURL();
$("<a>", {
href: url,
download: selected_date + selected_gln
})
.on("click", function() {$(this).remove()})
.appendTo("body")[0].click()
}
})
});
</script>
command handle code
public function handle()
{
$date = WeeklyTopSheetsData::max('report_date');
$accounts = REF_GA_GLN::Select('gln')->orderBy('account_name')->get();
foreach ($accounts as $account) {
$auxURL = 'http://localhost:8000/topsheet/' . $account['gln'] . '/' . $date . '/1';
$ch = curl_init();
echo $auxURL;
//set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $auxURL);
curl_setopt($ch, CURLOPT_HEADER, 0);
// grab URL and pass it to the browser
curl_exec($ch);
// close cURL resource, and free up system resources
curl_close($ch);
}
echo ' FIN';
}
}

Tableau Embed with jQuery and PHP passing parameters

I generally use Wordpress when building my internally facing dashboards with Tableau, but that will not work in this case so I am starting from scratch. I'm a novice with PHP and slightly above novice with jQuery, but I know my way around HTML. I need to pass an Okta javascript parameter into a Tableau embed. Below is my current code:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
var settings = {
url: "https://harmelin.okta.com/api/v1/users/me",
type: 'GET',
dataType: 'json',
contentType: 'application/json',
xhrFields: {
withCredentials: true
},
success: function (data) {
// alert(JSON.stringify(data));
},
error: function(err){
// alert(JSON.stringify(err));
}
}
jQuery.ajax(settings).done(function (success) {
console.log(success);
var raw = success.profile.login;
var email = raw.toLowerCase();
var $login = email.replace(/#[^#]+$/, '');
jQuery("#write-data").append($login);
});
</script>
</head>
<body>
<?php
// Tableau-provided functions for doing trusted authentication
require_once 'tableau_trusted.php';
?>
<div id="write-data"></div>
<?php
$user = 'jfedorowicz';
$server = 'dashboard1.harmelin.com';
$view = 'JoesPlayground/views/PTOStuff/Dashboard1?LCUsername=';
$theLogin = $login;
echo '<iframe src="';
echo get_trusted_url( $user,$server,$view$theLogin );
echo '" width="400" height="400"> </iframe>';
?>
</body>
Two problems:
1) What I am looking to do is pass $login (javascript variable) into $view. I 100% know that I did not do this right, but I cannot test because problem two.
2) I'm returning a 500 error: "Failed to load resource: the server responded with a status of 500 (Internal Server Error)" which I assume is a Tableau error but I cannot figure it out.
Any ideas? Thanks.
To generate authorization token you can use given code.
This code is working fine with all version upto 2018.3
/* PHP code to generate auth token */
$url = $dashboardURL . '/trusted';
$fields_string = "trusted_site=&username=" . $username;
$ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
//set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
$token = curl_exec($ch);
Now just pass this token with dashboard url in your view/html file.

How can I hide the API connection in a button

I have a code which I know how to perform certain API call with a link, it looks like this
<a class="btn btn-default" href="https://testapi.internet.bs/Domain/Transfer/Initiate?ApiKey='.$user.'&Password='.$pass.'&Domain='.$domain.$ext.'" role="button">Restart Transfer</a>
This works, but on the page of course it will show ApiKey=(actualKey) and the User and the PASSWORD which is not what I want. I understand this is how it works in a Link, but How can I do this with a button instead.
<form method="post" action="">
<button type="submit" class="btn btn-warning btn-lg btn-block" name="restartTransfer">Restart Transfer</button>
</form>
and Im guessing PHP action such as (Not saying this is the way, any way is appreciated using php, jquery or javascript)
if(isset($_POST['restartTransfer'])) {
}
Right now I do have it done like this
$(document).ready(function(){
$("button[name = 'restartTransfer']").click(function(){
window.location = "https://testapi.internet.bs/Domain/Transfer/Initiate?ApiKey=<?php print $user;?>&Password=<?php print $pass;?>&Domain=<?php print $domain;?>";
});
});
But this doesn't hide it, this just launches web browser window showing the API key user and pass..
How can I hide the API information in a button push (in the same page if possible)
The idea would be
Click this button
It loads the API call url (not shown)
Returns with a message "Complete" in a Div container called #message for sake of example
Thank you.
This might hide the actual URL from user in browser address bar. It will not, however, protect the credentials from being viewed either through profiling network requests, or viewing the source of the web page. I suggest using a PHP proxy to make it more secure.
$("button[name='restartTransfer']").click(function() {
$.ajax({
url: "https://testapi.internet.bs/Domain/Transfer/Initiate?ApiKey=<?php print $user;?>&Password=<?php print $pass;?>&Domain=<?php print $domain;?>",
type: 'GET',
dataType: 'text/plain',
success: function(data) {
$('#message').text(data); // print results
},
error: function(xhr) {
console.log('Error', xhr);
}
});
});
Using curl you can do it secure with php
<?php
class EBCommon{
public function call($sessionId, $sessionInfo, $realUser, $url, $parameters)
{
$apiUrl = "http://mycompany.edubrite.com/oltpublish/site/";
$curl_request = curl_init();
curl_setopt($curl_request, CURLOPT_URL, $apiUrl . $url);
curl_setopt($curl_request, CURLOPT_HEADER, 1);
curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_request, CURLOPT_POSTFIELDS, $parameters);
if($sessionId != null){
$cookieStr = "SESSION_ID=" . $sessionId;
if($sessionInfo != null){
$cookieStr .= "; SESSION_INFO=" . $sessionInfo;
}
//print($cookieStr . "\n");
curl_setopt($curl_request, CURLOPT_COOKIE, $cookieStr);
if($realUser != null){
$headerStr = array("REAL_UNAME: ".$realUser);
curl_setopt($curl_request, CURLOPT_HTTPHEADER, $headerStr);
}
}
$response = curl_exec($curl_request);
//print($response);
$error = curl_error($curl_request);
$result = array(
'body' => '',
'error' => '',
'http_code' => '',
'session_info' => '',
'session_id' => ''
);
if ( $error != "" )
{
$result['error'] = $error;
return $result;
}
$header_size = curl_getinfo($curl_request,CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$result['body'] = substr( $response, $header_size );
$result['http_code'] = curl_getinfo($curl_request,CURLINFO_HTTP_CODE);
curl_close($curl_request);
preg_match_all('/Set-Cookie:\s{0,}(?P<name>[^=]*)=(?P<value>[^;]*).*?$/im', $header, $cookies, PREG_SET_ORDER);
foreach ($cookies as $match) {
if($match["name"] == "SESSION_ID"){
$result['session_id'] = $match["value"];
}
if($match["name"] == "SESSION_INFO"){
$result['session_info'] = $match["value"];
}
}
return $result;
}
}
?>

Javascript setInterval method return always the same result from PHP method but I need changed data

So my problem is that I need to update some data from other site, and for calling that data I have php function where is the URL as parameter. ..So in JS I create a function that is in cycle with setInterval where I call that php function with URL parameter where are data stored, but it always return the same data..(data is actually playing track on stream, so data changed every +- 3 minutes) Data changes only on refresh page (f5) ..but I need update that data in background ..
this is the PHP function
function get_content($URL){
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $URL);
$data = curl_exec($ch);
curl_close($ch);
$data = str_replace(",,","},",$data);
$data = str_replace("}}]}}","}]}}",$data);
$data = str_replace("]}}","}]}}",$data);
$data = str_replace(",}}","}}}",$data);
$data = str_replace("}}]}}","}]}}",$data);
return $data;
In js I call in setInterval cycle only console.log to show result of php function..
console.log(<?php echo (get_content("http://server1.internetoveradio.sk:8809/status-json.xsl"));?>["icestats"]["source"])
Well, yeah. The PHP only gets called once in this case, the one time you echo out the contents of get_content();
If you want to get the content over and over again, use XmlHTTPRequest to call a PHP file which then returns the the result of get_content();
jQuery implements ajax ( XmlHTTPRequest ) to do exactly that.
jQuery.ajax({
url: "http://path.to/your_script.php",
method: "get",
complete: function( response ){
console.log(response);
}
});
edit:
Create a new .php file and paste this:
<?php
function get_content($URL){
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $URL);
$data = curl_exec($ch);
curl_close($ch);
$data = str_replace(",,","},",$data);
$data = str_replace("}}]}}","}]}}",$data);
$data = str_replace("]}}","}]}}",$data);
$data = str_replace(",}}","}}}",$data);
$data = str_replace("}}]}}","}]}}",$data);
return $data;
}
echo get_content("http://server1.internetoveradio.sk:8809/status-json.xsl");
In your html, add this:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
jQuery(document).ready(function(){
jQuery.ajax({
url: "http://path.to/your_script.php",
method: "get",
complete: function( response ){
console.log(response);
}
});
});
</script>
This is the most rudimentory version, but it should point you in the right direction hopefully.

Categories