【问题标题】:Google Places Nearby API Success 200, but returns "INVALID_REQUEST" in LaravelGoogle Places Nearby API Success 200,但在 Laravel 中返​​回“INVALID_REQUEST”
【发布时间】:2020-02-19 12:12:11
【问题描述】:

我正在尝试为 Google Places API 创建一个迭代爬虫。任何使用过他们的 API 的人都知道,响应每页仅包含 20 个结果,我正在尝试获取完整的结果列表,因此我创建了一个循环,如果 next_page_token 字段存在,它将执行一个函数。最奇怪的事情发生了,因为它成功检索并回显了前 20 个结果,但未能执行第二次搜索,但在 Laravel 中没有抛出任何错误。代码如下(在 Laravel 中)

public function getAllPlaces(){
        if (Auth::user()->id != '5') {
            return redirect('/userlanding')->with('error', 'Denied access');
        } else {
            $client = new Client();

            $types = 'park';

            $radius = '50000';

            $location = [

                'latitude' => '36.187740',

                'longitude' => '-92.731422'

            ];

            $keyword = '';

            $requestQuery = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={$location['latitude']},{$location['longitude']}&radius={$radius}&type={$types}{$keyword}&key=MYSUPERSECRETKEY";

            $response = $client->request('GET', $requestQuery);
            $statusCode = $response->getStatusCode();
            $body = $response->getBody()->getContents();

            $body = json_decode($body);

            $numofrecordspresent = 0;

            $data = $body->results;

            $results = collect();
            foreach($data as $result) {
                 $results->push($result;      
                 $numofrecordspresent = $numofrecordspresent + 1;
                }
            }

            if(isset($body->next_page_token)) {
                $loopData = [

                    'nexttoken' => $body->next_page_token,

                    'locationData' => $location,

                    'numofrecordspresent' => $numofrecordspresent,

                    'radius' => $radius,

                    'types' => $types,

                    'keyword' => $keyword,

                    'client' => $client,

                ];

                $this->loopedPlaceSearch($loopData);
            } else {
                return view('apireturnpage')->with('numofrecordspresent', $numofrecordspresent);
            }
        }
    }

    public function loopedPlaceSearch($loopData) {
        $client = new Client();

        $location = $loopData['locationData'];
        $numofrecordspresent = $loopData['numofrecordspresent'];
        $pagetoken = $loopData['nexttoken'];
        $radius = $loopData['radius'];
        $types = $loopData['types'];
        $keyword = $loopData['keyword'];

        $requestQuery = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={$location['latitude']},{$location['longitude']}&radius={$radius}&type={$types}{$keyword}&pagetoken={$pagetoken}&key=MYSUPERSECRETKEY";

        $response = $client->request('GET', $requestQuery);
        $statusCode = $response->getStatusCode();
        $body = $response->getBody()->getContents();

        $body = json_decode($body);

        $data = $body->results;

        $results = collect();
        foreach($data as $result) {
             $results->push($result;      
             $numofrecordspresent = $numofrecordspresent + 1;
            }
        }

        if (isset($body->next_page_token)) {
            $loopData = [

                'nexttoken' => $body->next_page_token,

                'locationData' => $location,

                'numofrecordspresent' => $numofrecordspresent,

            ];


            $this->loopedPlaceSearch($loopData);
        } else {
            return view('apireturnpage')->with('numofrecordspresent', $numofrecordspresent);
        }
    }

目前,详细说明我之前所说的,从 web.php 调用的第一个函数工作得很好,将所有 20 个结果推送到结果集合中,但是当有更多结果时(即 next_page_token存在),第二个函数被调用但在正文中返回“INVALID_REQUEST”。这非常奇怪,因为从使用但失败的第二个函数中获取确切的实际查询字符串并将其放入我的 URL 栏中会返回正确的响应,从而排除 API 调用中的任何拼写错误。

任何帮助将不胜感激,似乎是一个错误,我无法弄清楚为什么它不起作用。

【问题讨论】:

  • 您的浏览器可能会在必要的地方自动应用 URL 编码。从代码中发出请求时,通常不会发生这种情况。因此,您应该做的第一件事是将正确的 URL 编码应用于您插入到 URL 中的参数(或使用http_build_query 开头),而不是仅仅使用“手指交叉和希望”进行相当简单的字符串连接为最好”的态度。
  • 我可以添加编码,但是正如您在代码中看到的,在最初调用的函数和第二个函数中都进行了相同的调用过程,这意味着如果第一个请求成功,则不应该有任何原因第二个不应该?如果我错了,请纠正我,我经常这样做。

标签: php json laravel google-api google-places-api


【解决方案1】:

您的两个结果推送似乎都缺少右括号:

$results->push($result;      

我不知道这是否会解决它,但它困扰着我!

【讨论】:

  • OP here-在我的手机登录的旧帐户上-简单的推送代替了更长的操作,这不是问题的根源。实际代码被正确标点。回家后会修好。
【解决方案2】:

自从我发表这篇文章以来已经有一段时间了,但是对于那些刚刚发现这个问题的人来说,我想我会解释为什么会发生这种情况以及我是如何解决它的。事实证明,在脚本没有延迟的情况下,服务器尝试发出另一个请求,而另一个响应仍在返回,这导致了有问题的问题。通过在发出每个请求之前添加 sleep() 或 usleep() 可以非常简单地解决此问题,以防止同时进行多个调用。

编辑(5/10/20):这个解决方案仍然有效,但推理与我解释的不同。使用 usleep() 或 sleep() 函数解决此问题的真正原因是 Google 在其 API 端点上实施了瓶颈以防止误用。根据 API,它每 1-3 秒只允许一个请求,并且不再会导致此错误发生。我之所以知道这一点,是因为我直接联系了 Google,这是我从 Google 的技术支持员工那里收到的回复。

【讨论】:

    【解决方案3】:
    1. 将 php sleep(timeInSecounds>=1) 函数放在谷歌放置 api 的行中调用更多次之前。

    2. 另一点是您对 loopedPlaceSearch() 函数的递归调用。您将响应放在一个变量上,该变量的范围受他自己的函数限制。最好把你的反应告诉一个班员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 2013-05-25
      • 1970-01-01
      相关资源
      最近更新 更多