Guzzle Http Client ambiguous response - php

Here's my code in a different file
use Symfony\Component\DomCrawler\Crawler;
$guzzle = new GuzzleHttp\Client(['base_url' => 'http://pricematch.pk/mobile/samsung-galaxy-s6-80514-price-in-Pakistan']);
$response = $guzzle->get();
$crawler = new Crawler((string)$response->getBody());
echo $crawler->filter('.product-shop-wrapper .price')->text()."\r\n";
The url in this one is hardcoded and this one successfully echos the filtered text. When the same url/any url in the each loop in below code comes from a variable
$guzzle = new GuzzleHttp\Client(['base_url' => 'pricematch.pk/mobile-phone-prices-in-pakistan']);
$response = $guzzle->get();
$crawler = new Crawler((string)$response->getBody());
$crawler->filter('.product-name')->each(function ($node,$counter) {
echo $counter." ".$node->text()."\r\n";
$url=$node->filter('a')->extract(array('href'))[0]."\r\n";
echo $url."\r\n";
$url='http://pricematch.pk'.$url;
echo $url;
$guzzle = new GuzzleHttp\Client(['base_url' => $url]);
$response = $guzzle->get();
$crawler = new Crawler((string)$response->getBody());
the crawler throws an exception saying the current node list is empty. The href returns a relative url which I append with root url in the above code. I have printed the resultant url a lot many times. The filter throws exception even when the url is same as in code#1.
What am I doing wrong? Update 2: I just found out that data in code2 crawler is coming from
pricematch.pk/mobile-phone-prices-in-pakistan
Where it should be coming from
$url
What's goin on here?

Stupid me. While extracting URL in above code, I concatenated the newline character which got maybe encoded the URL to come out as __ at the end of the URL which basically changed the URL and hence the changed response.

Related

Navigating forms and grabbing DOM-Elements from a website using Guzzle/Goutte (PHP, Debugging)

I'm fairly new to PHP and playing around with Goutte/Guzzle to grab some basic information from a website after filling out a few forms.
However I have problems finding issues (there might be a ton of them) since I could not find a way to display or console log any of the results or problems. The script finishes with Code 0 but does not return anything. A tip on how to print out what is currently stored in $client would already go a long way.
Here is the whole code I'm trying to run with a bunch of comments for clarification. I'm sorry for using such a large block, but any of this could have issues.
<?php
use Goutte\Client;
use GuzzleHttp\Client as GuzzleClient;
class grabPlate
{
// WKZ
public function checkPlate
{
$goutteClient = new Client();
$guzzleClient = new GuzzleClient(array(
'cookies' => true,
'timeout' => 60,
));
$goutteClient->setClient($guzzleClient);
$crawler = $goutteClient->request('GET', 'https://kfz-portal.berlin.de/kfzonline.public/start.html?oe=00.00.11.000000');
//Click the first "Start" in the top left
$link = $crawler
->filter('a:contains("Start")')
->eq(0)
->link()
;
$crawler = $client->click($link);
//Check checkbox, fill in name and press the button
$buttonCrawlerNode = $crawler->selectButton('Weiter');
$form = $buttonCrawlerNode->form();
$form['gwt-uid-1']->tick();
$form['select2-hidden-accessible']->select('Herr');
$form['gwt-uid-4'] = 'John';
$form['gwt-uid-5'] = 'Doe';
$client->submit($form);
//Fill some Data into the forms and search
$buttonCrawlerNode = $crawler->selectButton('Button-3616');
$form = $buttonCrawlerNode->form();
$form['.kfzonline-KennzeichenGrossEb'] = 'AB';
$form['.kfzonline-KennzeichenGrossEn'] = '123';
$client->submit($form);
//Extract collection
$info = $crawler->extract('.collection');
//return 1 if something is inside collection, 0 if it's empty
if($info == NULL) {
return 1;
} else {
return 0;
}
}
}
?>
As I said just running the script in PHPStorm returns the status 0. However when plugging it into an API and accessing it, I get a server timeout response.
You should either use a Debugging. Install xDebug to do so in PHP. This is also easy to integrate into Phpstorm.
Alternatively use var_dump() for printing out debug information about variables of any type to console.
You can display the requested page inside your php page, you have to add this snippet :
$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://www.facebook.com/');
echo $res->getBody();

Zend HTTP Client Invalid URI supplied?

I'm having trouble using Zend HTTP on a URL:
$bestBuyClient = new Zend_Http_Client('https://api.bestbuy.com/v1/products(search=pizza&salePrice>10&salePrice<15)?apiKey=MyKeyHere&page=1&numItems=10&format=json&show=sku&name&productId&type&regularPrice&salePrice&upc&modelNumber&image&largeFrontImage&mediumImage&thumbnailImage&largeImage&shortDescription&longDescription');
$response = $bestBuyClient->request();
$json="";
if($response->isSuccessful()){
$jsonTxt=$response->getBody();
$json = #json_decode($jsonTxt,true);
}
$jsonProducts=$json;
return $jsonProducts;
For some reason, this gives me an error:
Invalid URI supplied
Whats wrong this this specific url?
Edit: In PostMan or browser request sends proper data.
Can you change:
$bestBuyClient = new Zend_Http_Client('https://api.bestbuy.com/v1/products(search=pizza&salePrice>10&salePrice<15)?apiKey=MyKeyHere&page=1&numItems=10&format=json&show=sku&name&productId&type&regularPrice&salePrice&upc&modelNumber&image&largeFrontImage&mediumImage&thumbnailImage&largeImage&shortDescription&longDescription');
$response = $bestBuyClient->request();
To
$shoppableClient = new Zend_Http_Client(sprintf('https://api.bestbuy.com/v1/products'."%s?%s", urlencode('(search=pizza&salePrice>10&salePrice<15)'), 'apiKey=MyKeyHere&page=1&numItems=10&format=json&show=sku&name&productId&type&regularPrice&salePrice&upc&modelNumber&image&largeFrontImage&mediumImage&thumbnailImage&largeImage&shortDescription&longDescription'));
Please let me know if works :).

Implementing curl in ZF2

I am trying to establish a communication with two zf2 application via curl.The required response is in xml. So far I could establish the connection and xml is returned as response.
The problem
The problem is that,I can't iterate on my xml response.Whenever I var_dump and view source code of my $response->getContent,I get as
string(142) "<?xml version="1.0" encoding="UTF-8"?>
<myxml>
<login>
<status>success</status>
<Err>None</Err>
</login>
</myxml>
"
and when I simply var_dump my $response,I get an object(Zend\Http\Response)#440.
simplexml_load_string($response->getContent()) gives me a blank page.
Also print $data->asXML() gives me Call to a member function asXML() on a non-object error.What am I doing wrong here?
Curl request action
$request = new \Zend\Http\Request();
$request->getHeaders()->addHeaders([
'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'
]);
$request->setUri('http://localhost/app1/myaction');
$request->setMethod('POST'); //uncomment this if the POST is used
$request->getPost()->set('curl', 'true');
$request->getPost()->set('email', 'me#gmail.com');
$request->getPost()->set('password', '2014');
$client = new Client;
$client->setAdapter("Zend\Http\Client\Adapter\Curl");
$response = $client->dispatch($request);
var_dump($response);//exit;
//$response = simplexml_load_string($response->getContent());
//echo $response;exit;
return $response;
Curl response action
$php_array=array(
'login'=>array(
'status'=>'failed','Err'=>'Unauthorised Access'
)
);
$Array2XML=new \xmlconverter\Arraytoxml;
$xml = $Array2XML->createXML('myxml', $php_array);
$xml = $xml->saveXML();
//echo $xml;exit;
$response = new \Zend\Http\Response();
$response->getHeaders()->addHeaderLine('Content-Type', 'text/xml; charset=utf-8');
$response->setContent($xml);
return $response;
The Array2XML can be found here
Any ideas?
when I simply var_dump my $response,I get an object(Zend\Http\Response)#440
This is correct and it tells you the type of $response.
simplexml_load_string($response->getContent()) gives me a blank page.
This is correct because despite this function can return a value expressible to an empty string, it does not create any output on it's own and therefore the blank page is to be expected.
Any ideas?
First of all you should formulate a proper problem statement with your question. All you say so far therein is to be expected, so your question is not clear at best.
Second you need to do proper error handling and do some safe programming:
$buffer = $response->getContent();
if (!is_string($buffer) || !strlen($buffer) || $buffer[0] !== '<') {
throw new RuntimeException('Need XML string, got %s', var_export($buffer, 1));
}
$xml = simplexml_load_string($buffer);
if (false === $xml) {
throw new RuntimeException('Unable to parse response string as XML');
}
Which is: For every parameter you get, validate it. For every function or method result you receive check the post-conditions. Before you call a function or method, check the pre-conditions for each parameter.
Log errors to file and handle uncaught exceptions.
As an additional idea: Drop the use of the array to XML function and replace it with a library that is maintained. In your case it's perhaps easier to just use SimpleXML your own to create the XML.

Instagram API: Get All User Media API and Store to File

I know the way to get all user media in instagram api with pagination. And we must request again with pagination url provided to get next photos.
I just wonder if i can save all of json api response include with next photos in pagination to one flat file for caching. The purpose is i can call all photos value from one file only, e.g: cache.json.
Is there a way to realize that in PHP Code if possible? Like using file_get and file_put function. Any help is appreciated so much :)
Here's my code, but need a tweak to fix it. Im using this wrapper https://github.com/cosenary/Instagram-PHP-API
require 'instagram.class.php';
$cache = './cache.json';
$instagram = new Instagram($accessToken);
$instagram->setAccessToken($accessToken);
$response = $instagram->getUserMedia($userID,$settings['count']);
do {
if($response){
file_put_contents($cache,json_encode($response)); //Save as json
}
} while ($response = $instagram->pagination($response));
echo 'finish';
With this code i getting the last pagination only. It seems the code overwrite the cache.json file, not adding.
Maybe you can suggest me how to fix it become adding, not overwriting.
-- Edit --
My code now working but not perfect, maybe you can try and fix it.
<?php
include('conf.php');
require 'instagram.class.php';
$cache = './cache_coba.json';
$instagram = new Instagram($accessToken);
$instagram->setAccessToken($accessToken);
$response = $instagram->getUserMedia($userID,$settings['count']);
while ($response = $instagram->pagination($response)) {
if($response){
$opn = file_get_contents($cache);
$opn .= json_encode($response);
file_put_contents($cache, $opn);
}
}
echo 'finish';
?>

Why is JSON not being returned from GiantBomb API

Im trying to use the GiantBomb api to query video games, and currently when I enter the URL into a browser, it works just fine. The Json data shows up.
Heres an example url..
http://www.giantbomb.com/api/search/?api_key=83611ac10d0dfghfgh157177ecb92b0a5a2350c59a5de4&query=Mortal+Kombat&format=json
But when I try to use my php wrapper that Im just starting to build, it returns html??
Heres the start of my wrapper code....(very amateur for now)
You'll notice in the 'request' method, Ive commented out the return for json_decode($url), because when I uncomment it, the page throws a 500 error??? So I wanted to see what happends when I just echo it. And it echos an html page. Surely it should just echo what is shown, when you just enter that url into the browser, no?
However...if I replace the url with say a GoogleMap url, it echoes out Json data just fine, without using json_decode. Any ideas as to wahts going on here????
class GiantBombApi {
public $api_key;
public $base_url;
public $format;
function __construct() {
$this->format="&format=json";
$this->api_key = "83611ac10d0d157177ecb92b0a5a2350c59a5de4";
$this->search_url = "http://www.giantbomb.com/api/search/?api_key=".$this- >api_key."&query=";
}
public function search($query){
$query = urlencode($query);
$url = $this->search_url.$query.$this->format;
return $this->request($url);
}
public function request($url) {
$response = file_get_contents($url);
echo $response;
//return json_decode($response, true);
}
}
//TESTING SECTION
$games = new GiantBombApi;
$query = $_GET['search'];
echo $games->search($query);
I ran a few requests through Postman and it seems that the api looks at the mime-type as well as the query string. So try setting a header of "format" to "json".

Categories