Getting json data from a webpage using PHP - php

I am trying to fetch a response from here (example url), and first, I thought I should use file_get_contents()
When I tried this, I got the following error:
Warning: file_get_contents(https://steamcommunity.com/market/pricehistory/?country=US&currency=1&appid=730&market_hash_name=SG%20553%20|%20Damascus%20Steel%20(Factory%20New)): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request
I know this is because it is converting & to &. I have tried numerous ways to counter this, however they have all failed and after a quick google I came to the conclusion that file_get_contents() converts & to & automatically.
My next step was to try curl. I tried the below code first:
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://steamcommunity.com/market/pricehistory/?country=US&currency=1&appid=730&market_hash_name='.$hash,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.2 (KHTML, like Gecko) ChromePlus/4.0.222.3 Chrome/4.0.222.3 Safari/532.2'
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
But this returned ‹ŠŽÿÿ)»L as the response. I wondered if this was to do with json encoding, so I tried putting it through json_decode() but it didn't work.
Next, I tried:
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://steamcommunity.com/market/pricehistory/',
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.2 (KHTML, like Gecko) ChromePlus/4.0.222.3 Chrome/4.0.222.3 Safari/532.2',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => array(
country => "US",
currency => 1,
appid => 730,
market_hash_name => "SG%20553%20|%20Damascus%20Steel%20(Factory%20New)"
)
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
But again got the response ‹ŠŽÿÿ)»L.
What does this response mean, and can I parse it? If not, how should I correctly fetch this data? Furthermore, why didn't file_get_contents() work?

I'm pretty sure this is happening because you need some type of access token to access the steam web API.
See this answer on SO.
Essentially, Steam is returning an error with the "400 Bad Request" status. This error can be ignored, however, by doing this:
<?php
$url = "https://steamcommunity.com/market/pricehistory/?country=US&currency=1&appid=730&market_hash_name=SG%20553%20%7C%20Damascus%20Steel%20(Factory%20New)";
$context = stream_context_create(array(
'http' => array(
'ignore_errors'=>true,
'method'=>'GET'
// for more options check http://www.php.net/manual/en/context.http.php
)
));
$response = file_get_contents($url, false, $context);
echo $response; // returns "[]"
?>
Make sure you take a look at this answer on SO.

May be your response is gzip, try to use CURLOPT_ENCODING.
curl_setopt($curl ,CURLOPT_ENCODING, '')
If you use https don't forget to disable CURLOPT_SSL_VERIFYPEER.
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false)
One thing, if I follow your link with my browser and open my debug console.
I see you request have a 400 Status code (Bad Request).

I cant say about your enpoint, but you can get around your Bad Request error by using urlencode():
$url = urlencode('https://steamcommunity.com/market/pricehistory/?country=US&currency=1&appid=730&market_hash_name=SG%20553%20%7C%20Damascus%20Steel%20(Factory%20New))'
file_get_contencts($url);

Related

PHP file_get_contents returns with a 400 Error

My problem is pretty straightforward, but I cannot for the life of me figure out what is wrong. I've done something similar with another API, but this just hates me.
Basically, I'm trying to get information from https://owapi.net/api/v3/u/Xvs-1176/blob and use the JSON result to get basic information on the user. But whenever I try to use file_get_contents, it just returns
Warning: file_get_contents(https://owapi.net/api/v3/u/Xvs-1176/blob): failed to open stream: HTTP request failed! HTTP/1.1 400 BAD REQUEST in Z:\DevProjects\Client Work\Overwatch Boost\dashboard.php on line
So I don't know what's wrong, exactly. My code can be seen here:
$apiBaseURL = "https://owapi.net/api/v3/u";
$apiUserInfo = $gUsername;
$apiFullURL = $apiBaseURL.'/'.$apiUserInfo.'/blob';
$apiGetFile = file_get_contents($apiFullURL);
Any help would be largely appreciated. Thank you!
You need to set user agent for file_get_contents like this, and you can check it with this code. Refer to this for set user agent for file_get_contents.
<?php
$options = array('http' => array('user_agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0'));
$context = stream_context_create($options);
$response = file_get_contents('https://owapi.net/api/v3/u/Xvs-1176/blob', false, $context);
print_r($response);
That's what page is sending: "Hi! To prevent abuse of this service, it is required that you customize your user agent".
You can customize it using curl like that:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://owapi.net/api/v3/u/Xvs-1176/blob");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
$output = curl_exec($ch);
$output = json_decode($output);
if(curl_getinfo($ch, CURLINFO_HTTP_CODE) !== 200) {
var_dump($output);
}
curl_close($ch);
If you do curl -v https://owapi.net/api/v3/u/Xvs-1176/blob you will get a response and you will see what headers cURL includes by default. Namely:
> Host: owapi.net
> User-Agent: curl/7.47.0
> Accept: */*
So then the question is, which one does owapi care about? Well, you can stop cURL from sending the default headers like so:
curl -H "Accept:" -H "User-Agent:" -H "Host:" https://owapi.net/api/v3/u/Xvs-1176/blob
... and you will indeed get a 400 response. Experimentally, here's what you get back if you leave off the "Host" or "User-Agent" headers:
{"_request": {"api_ver": 3, "route": "/api/v3/u/Xvs-1176/blob"}, "error": 400, "msg": "Hi! To prevent abuse of this service, it is required that you customize your user agent."}
You actually don't need the "Accept" header, as it turns out. See the PHP docs on how to send headers along with file_get_contents.

Error "HTTP code 405 Method not allowed" when using CURL for a GET request

I want to fetch response of a GET request by CURL, but get the Error "HTTP/1.1 405 Method Not Allowed" and no content is returned (except the header).
The following is my code.
$url = "http://api.example.com/Q5PLCmwYzho=/7avEU7ptYyummfheg9!0KA==?aqPI=93566&aqIIO=false&aqIP=false&aqSK=0&aqTK=14&aqSO=date&aqCI=0"
$options = array(
CURLOPT_URL => $url,
CURLOPT_HTTPGET => true, //set request type post or get
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => true,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36',
CURLOPT_HTTPHEADER => array(
'Accept: application/json, text/javascript, */*; q=0.01',
'Accept-Encoding: gzip, deflate, sdch',
//'Content-Type: application/json; charset=utf-8',
//'Access-Control-Allow-Origin: http://localhost:14189',
//'Origin: http://www.example.com',
//'Host: api.example.com',
//'Access-Control-Allow-Credentials: true',
),
CURLOPT_COOKIE => 'Cookie:scarab.profile=%2293566%7C1465411024%22; scarab.mayAdd=%5B%7B%22i%22%3A%2293566%22%7D%2C%7B%22i%22%3A%22117313%22%7D%5D; _ceg.s=o8gwtw; _ceg.u=o8gwtw; _gat=1; _dc_gtm_UA-13212406-1=1; DK-Client=CWUU,09b6ab76-f662-48b3-a1e6-f08779519236; __auc=764bbe2e155314db7ac1a950571; scarab.visitor=%22566B1DCD74FCD3A5%22; _ga=GA1.2.412464545.1465411024'
);
$ch = curl_init();
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err; //no error!
$header['errmsg'] = $errmsg;
$header['content'] = json_decode($content); // no content!
echo $response['http_code']; //output: 405
I checked the corresponding ajax request in the webpage and every curl options seems to be set correctly. The details (captured from chrome Dev tools) are shown in the image.
![1]: http://i.stack.imgur.com/XW8k1.png
What am I missing?? I searched a lot but couldn't solve the problem! I know one of the causes of this error is using an unauthorized request method for curl but the corresponding AJAX call uses GET method and get the result.
What is wrong? Any help would be appreciated.
Update: I wrote an AJAX request to fetch the data in local server (localhost) and got this error : "Cross-Origin Request Blocked". It means that I can't make request to a different domain (api.example.com) from localhost. Are there any workarounds or hack to get the response content from that server?
I was getting this error in Postman. In my case it was because I was using GET when I should have used POST. Also I was using GET params instead of POST params. Checking the proper method (specified in my java code) and using the "code" button in postman to display the curl CLI helped me.
Try to send User-Agent in your request.
If page that you requested needs any authorization then you need to send cookies with auth data.

PHP Curl for encrypted pages

I do a php curl to this website
http://www.hoovers.com/company-information/company-search.html
But it returned 404. Looks like something encrypted or what.
Can you give some clue about this problem.
Thanks
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://www.hoovers.com/company-information/company-search.html',
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
Looks like their web server is rejecting requests based on HTTP headers. Or it might be on the application level as well. Try this
<?php
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HEADER=>1,
CURLOPT_URL => 'http://www.hoovers.com/company-information/company-search.html',
CURLOPT_HTTPHEADER=> array(
'User-Agent: Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0', 'Accept-Language: en-US,en;q=0.5'
)
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
//debug
print_r($resp);
?>

cURL set Accept-Language not working

I am trying to make a cURL request. The problem I am facing is that the page have different text depending on which country it is. So I would like the cURL request to have the language en_US (English). So it will get the English text on the website.
Currently I have this code, but its not getting the US text.
$url = 'http://testurl.com'; // Not the real URL
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_HTTPHEADER => array("Accept-Language: en-US;q=0.6,en;q=0.4"),
CURLOPT_USERAGENT => Array("User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.15) Gecko/20080623 Firefox/2.0.0.15"),
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$err = curl_errno($ch);
$errmsg = curl_error($ch);
$header = curl_getinfo($ch);
curl_close($ch);
echo htmlspecialchars($content);
So to make this simple, I would like the cURL request to send the request with the US language, if possible.
Right now it has the language 'dutch' I think this is because my hosting server is located in Netherlands. So therefore it is deutch. But I would like to change it to English.

Flickr API sometimes returns false, but usually works, why?

I'm constructing this URL with PHP and getting the result from Flickr with CURL.
http://api.flickr.com/services/rest?api_key=APIKEY&format=php_serial&method=flickr.photosets.getPhotos&photoset_id=72157594403088940&per_page=200&extras=description,url_l,url_c,url_z,url_m,url_n,url_s,url_t
There is a real API key there of course. Anyway it sometimes returns bool(false), sometimes the proper list of images. Usually it's like first time check on a given day returns false, then after a refresh it gets the list properly. My CURL function I use to get the result:
function file_get_contents_curl($url, $curlopt = array()){
if(in_array('curl', get_loaded_extensions())){
$ch = curl_init();
$default_curlopt = array(
CURLOPT_TIMEOUT => 2,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 AlexaToolbar/alxf-1.54 Firefox/3.6.13 GTB7.1"
);
$curlopt = array(CURLOPT_URL => $url) + $curlopt + $default_curlopt;
curl_setopt_array($ch, $curlopt);
$response = curl_exec($ch);
if($response === false)
trigger_error(curl_error($ch));
curl_close($ch);
return $response;
}else{
return file_get_contents($url);
}
}
What is this and why does it happen? Maybe it has something to do with my CURL function (my best bet)?
You have set the CURLOPT_TIMEOUT to 2 seconds. Can you verify if the code times out before the execution completes. If so, try increasing it a bit and see if it works.
Just a guess.

Categories