Scraping Keyword Suggestions from Google - php

I'm currently working to scrape keyword suggestion from Google. This is the script I'm working with:
<?php
function text_between($start,$end,$string) {
if ($start != '') {$temp = explode($start,$string,2);} else {$temp = array('',$string);}
$temp = explode($end,$temp[1],2);
return $temp[0];
}
function gsscrape($keyword) {
$keyword=str_replace(" ","+",$keyword);
global $kw;
$data=file_get_contents('http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl=en-US&q='.$keyword);
$data=explode('[',$data,3);
$data=explode('],[',$data[2]);
foreach($data as $temp) {
$kw[]= text_between('"','"',$temp);
}
}
#simple to use, just use yourscriptname.php?keywords
if ($_SERVER['QUERY_STRING']!='') {
gsscrape($_SERVER['QUERY_STRING']);
foreach ($kw as $keyword) {
gsscrape($keyword);
}
//sorted and duplicates removed
sort(array_unique($kw));
#all results echoed with break
foreach ($kw as $keywords) {
echo $keywords. "<br />";
}
}
?>
When accessing directly through the URL Google will give me this response for the keyword money:
["money",["moneygram","money network","money mutual","money trees lyrics","moneyball","moneypak","money","money converter","money order","money2india"]]
However, for some reason when I test it on my website, it's just showing this:
moneygram
moneygram
What needs to be changed so that it displayed each of the keywords like this?
moneygram, money network, money mutual, money trees lyrics, moneyball, moneypak, money, money converter, money order, money2india

This is valid JSON, use json_decode and you are done!
var_dump(json_decode('["money",["moneygram","money network","money mutual","money trees lyrics","moneyball","moneypak","money","money converter","money order","money2india"]]'));
edit - complete example;
<?php
function getKeywordSuggestionsFromGoogle($keyword) {
$keywords = array();
$data = file_get_contents('http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl=en-US&q='.urlencode($keyword));
if (($data = json_decode($data, true)) !== null) {
$keywords = $data[1];
}
return $keywords;
}
var_dump(getKeywordSuggestionsFromGoogle('money'));

To get the data as an array use this:
function gsscrape($keyword) {
return json_decode(utf8_decode(file_get_contents('http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl=en-US&q='.urlencode($keyword))),true);
}

Related

Decode API response in PHP from Google Maps

I'm struggling to get the "Adams County" from "administrative_area_level_2" type
from this api response
http://maps.googleapis.com/maps/api/geocode/json?latlng=39.76144296429947,-104.8011589050293&sensor=false .
I simply need to output the county based on the latitude and longitude.
$query = #unserialize(file_get_contents('http://maps.googleapis.com/maps/api/geocode/json?latlng=39.76144296429947,-104.8011589050293&sensor=false'));
echo 'Hello visitor from '.$query["response"];
This is what I have for now. Thank you.
You will need to use a recursive search and keep track of the previous found item in the result array.
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=39.76144296429947,-104.8011589050293&sensor=false';
$query = #json_decode(file_get_contents($url),true);
$address_components = $query['results'][0]['address_components'];
array_walk_recursive( $address_components,
function($item, $key) use(&$prev_item, &$stop){
if($item == 'administrative_area_level_2'){
$stop = true;
}
else {
if(!$stop)
$prev_item = $item;
}
});
var_dump($prev_item);
Use json_decode instead of unserialize, as the response is in JSON format.
Then just iterate the items in a loop or two, for example:
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=39.76144296429947,-104.8011589050293&sensor=false'; $response = json_decode(file_get_contents($url), true);
if (empty($response['results'])) {
// handle error
}
$long_name = null;
foreach ($response['results'] as $r) {
if (empty($r['address_components']) || empty($r['types']))
continue;
if (array_search('administrative_area_level_2', $r['types']) === false)
continue;
foreach ($r['address_components'] as $ac) {
if (array_search('administrative_area_level_2', $ac['types']) !== false) {
$long_name = $ac['long_name'];
break;
}
}
}
echo $long_name;
Output
Adams County

Data Not Being Parsed Correctly

I have a simple data format that goes as follows:
stuff/stuff/stuff
An example would be:
data/test/hello/hello2
In order to retrieve a certain piece of data, one would use my parser, which tries to do the following:
In data/test/hello/hello2
You want to retrieve the data under data/test (which is hello). My parser's code is below:
function getData($data, $pattern)
{
$info = false;
$dataLineArray = explode("\n", $data);
foreach($dataLineArray as &$line)
{
if (strpos($line,$pattern) !== false) {
$lineArray = explode("/", $line);
$patternArray = explode("/", $pattern);
$iteration = 0;
foreach($lineArray as &$lineData)
{
if($patternArray[$iteration] == $lineData)
{
$iteration++;
}
else
{
$info = $lineData;
}
}
}
}
return $info;
}
However, it always seems to return the last item, which in this case is hello2:
echo getData("data/test/hello/hello2", "data/test");
Gives Me;
hello2
What am I doing wrong?
If you want the first element after the pattern, put break in the loop:
foreach($lineArray as $lineData)
{
if($patternArray[$iteration] == $lineData)
{
$iteration++;
}
elseif ($iteration == count($patternArray))
{
$info = $lineData;
break;
}
}
I also check $iteration == count($patternArray) so that it won't return intermediate elements, e.g.
/data/foo/test/hello/hello2
will return hello rather than foo.
P.S. There doesn't seem to be any reason to use references instead of ordinary variables in your loops, since you never assign to the reference variables.

PHP Performing Calculations with Multidim Array

I've currently have a multidim array with a planet and it's relative gravity value.
([0][0] = planet and [0][1] = relative gravity).
On my page I have a form where the user submits the weight of an item and the planet they wish to see it's weight on. What I'm trying to do is take the weight the user entered and multiply it by the relative gravity of the specific planet they chose.
My initial attempts have been to use something like this:
<?php
$file = fopen("PLANET.txt", "r");
$planets = array();
while(!feof($file)) {
$line = fgets($file);
$value = explode(" ", $line);
array_push($planets, $value);
}
if(isset($_POST['weight']) && isset($_POST['planet'])) {
while($x=0;x<count($planets);x++) {
if($_POST['planet'] == $planets[x][0]) {
$final_weight = $_POST['weight'] * $planets[x][1];
}
}
}
?>
However it does not seem to be working... I am brand new to PHP and I could be making a dumb mistake but I can't seem to find it, any help would be much appreciated.
EDIT:
Ok here is what I have now and it seems to be working, thank you guys very much. Feel so dumb for making those mistakes!
for($x=0;$x<count($planets);$x++) {
if($_POST['planet'] == $planets[$x][0]) {
$final_weight = $_POST['weight'] * $planets[$x][1];
}
}
Your while loop should look like that (note the additional $ signs):
while($x=0;$x<count($planets);x++) {
if($_POST['planet'] == $planets[$x][0]) {
$final_weight = $_POST['weight'] * $planets[$x][1];
}
}
EDIT: The above is complete nonsense. No idea what got into me. It should of course be:
for($x=0;$x<count($planets);x++) {
if($_POST['planet'] == $planets[$x][0]) {
$final_weight = $_POST['weight'] * $planets[$x][1];
}
}

Multi-dimensional array search to preserve parent

TL;DR
I have this data: var_export and print_r.
And I need to narrow it down to: http://pastebin.com/EqwgpgAP ($data['Stock Information:'][0][0]);
How would one achieve it? (dynamically)
I'm working with vTiger 5.4.0 CRM and am looking to implement a function that would return a particular field information based on search criteria.
Well, vTiger is pretty weakly written system, looks and feels old, everything comes out from hundreds of tables with multiple joins (that's actually not that bad) etc., but job is job.
The need arose from getting usageunit picklist from Products module, Stock Information block.
Since there is no such function as getField();, I am looking forward to filter it out from Blocks, that is actually gathering the information about fields also.
getBlocks(); then calls something close to getFields();, that again something close to getValues(); and so on.
So...
$focus = new $currentModule(); // Products
$displayView = getView($focus->mode);
$productsBlocks = getBlocks($currentModule, $displayView, $focus->mode, $focus->column_fields); // in theory, $focus->column_fields should/could be narrowed down to my specific field, but vTiger doesn't work that way
echo "<pre>"; print_r($productsBlocks); echo "</pre>"; // = http://pastebin.com/3iTDUUgw (huge dump)
As you can see, the array under the key [Stock Information:], that actually comes out from translations (yada, yada...), under [0][0] contains information for usageunit.
Now, I was trying to array_filter(); the data out from there, but only thing I've managed to get is $productsBlocks stripped down to only contain [Stock Information:] with all the data:
$getUsageUnit = function($value) use (&$getUsageUnit) {
if(is_array($value)) return array_filter($value, $getUsageUnit);
if($value == 'usageunit') return true;
};
$productsUsageUnit = array_filter($productsBlocks, $getUsageUnit);
echo "<pre>"; print_r($productsUsageUnit); echo "</pre>"; // = http://pastebin.com/LU6VRC4h (not that huge of a dump)
And, the result I'm looking forward to is http://pastebin.com/EqwgpgAP, that I've manually got by print_r($productsUsageUnit['Stock Information:'][0][0]);.
How do I achieve this? (dynamically...)
function helper($data, $query) {
$result = array();
$search = function ($data, &$stack) use(&$search, $query) {
foreach ($data as $entry) {
if (is_array($entry) && $search($entry, $stack) || $entry === $query) {
$stack[] = $entry;
return true;
}
}
return false;
};
foreach ($data as $sub) {
$parentStack = array();
if ($search($sub, $parentStack)) {
$result[] = $parentStack[sizeof($parentStack) - 2];
}
}
return $result;
}
$node = helper($data, 'usageunit');
print_r($node);

Build JSON with php echo statements

Am trying to build a JSON array from a php array
This is my function in my controller
function latest_pheeds() {
if($this->isLogged() == true) {
$this->load->model('pheed_model');
$data = $this->pheed_model->get_latest_pheeds();
$last = end($data);
echo "[";
for($i = 0; $i < count($data); $i++) {
echo '{"user_id":"'.$data[$i][0]['user_id'].'",';
echo '"pheed_id":"'.$data[$i][0]['pheed_id'].'",';
echo '"pheed":"'.$data[$i][0]['pheed'].'",';
echo '"datetime":"'.$data[$i][0]['datetime'].'",';
if($i == count($data)) {
echo '"comments":"'.$data[$i][0]['comments'].'"}';
}else {
echo '"comments":"'.$data[$i][0]['comments'].'"},';
}
}
echo "]";
}
return false;
}
It returns a json array like this
[{"user_id":"9","pheed_id":"2","pheed":"This is my first real pheed, its got potential ","datetime":"1313188898","comments":"0"},{"user_id":"9","pheed_id":"11","pheed":"My stomach being hurting all day","datetime":"1313422390","comments":"0"},{"user_id":"9","pheed_id":"11","pheed":"My stomach being hurting all day","datetime":"1313422390","comments":"0"},{"user_id":"9","pheed_id":"10","pheed":"Thank God for stackoverflow.com ","datetime":"1313358605","comments":"0"},]
But i cant seem to access it with jquery
I believe the problem rests with the trailing comma at the end of your array.
Rather than try to encode it yourself, use PHP's json_encode function. It's been tested and verified many, many times, so you don't have to reinvent the wheel.
Already voted up #derekerdmann, but thought I would add...
Your code will work, if you change:
if($i == count($data)) {
to
if($i == count($data) - 1) {
But, don't do that. If you are just putting everything from each member of the $data array into the json, then you should be able to just json_encode($data). If you are only pulling out certain parts, then build up a secondary array of your filtered data and json_encode that instead.
function latest_pheeds() {
if($this->isLogged() == true) {
$this->load->model('pheed_model');
$data = $this->pheed_model->get_latest_pheeds();
$filtered_items = array();
foreach ($data as $member) {
$filtered_item = array();
$filtered_item['user_id'] = $member['user_id'];
$filtered_item['pheed_id'] = $member['pheed_id'];
...
...
$filtered_items[] = $filtered_item;
}
echo json_encode($filtered_items);
}
return false;
}

Categories