构建脚本代码以将数据从 Google 个位置 API 返回到 Google 个工作表

Building script code to get data from Google Places API back to Google Sheets

我正在尝试为 Google 表格构建一个函数,以从 Google 个地方 API.

中的某些地方获取完整地址

据我了解,为此我需要:

a) 构建要在 Google 地点 API 上拍摄的查询(示例:https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=cordoaria%20sao%20leopoldo%brasil&inputtype=textquery&key=AI***)

{
   "candidates" : [
      {
         "place_id" : "ChIJ49bv_6lpGZURk4Hl8w31LRQ"
      }
   ],
   "debug_log" : {
      "line" : []
   },
   "status" : "OK"
}

b) 在 Google 个位置 API

中执行该查询

c) 获取地点 ID(它返回给我这个地点 ID ChIJ49bv_6lpGZURk4Hl8w31LRQ)

d) 在 Google 处再次搜索 API (示例:https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJ49bv_6lpGZURk4Hl8w31LRQ&key=AI****)

{
   "html_attributions" : [],
   "result" : {
      "address_components" : [
         {
            "long_name" : "10",
            "short_name" : "10",
            "types" : [ "street_number" ]
         },
         {
            "long_name" : "Avenida Padre Santini",
            "short_name" : "Av. Padre Santini",
            "types" : [ "route" ]
         },
         {
            "long_name" : "Jardim America",
            "short_name" : "Jardim America",
            "types" : [ "sublocality_level_1", "sublocality", "political" ]
         },
         {
            "long_name" : "São Leopoldo",
            "short_name" : "São Leopoldo",
            "types" : [ "administrative_area_level_2", "political" ]
         },
         {
            "long_name" : "Rio Grande do Sul",
            "short_name" : "RS",
            "types" : [ "administrative_area_level_1", "political" ]
         },
         {
            "long_name" : "Brazil",
            "short_name" : "BR",
            "types" : [ "country", "political" ]
         },
         {
            "long_name" : "93035-280",
            "short_name" : "93035-280",
            "types" : [ "postal_code" ]
         }
      ],
      "adr_address" : "\u003cspan class=\"street-address\"\u003eAv. Padre Santini, 10\u003c/span\u003e - \u003cspan class=\"extended-address\"\u003eJardim America\u003c/span\u003e, \u003cspan class=\"locality\"\u003eSão Leopoldo\u003c/span\u003e - \u003cspan class=\"region\"\u003eRS\u003c/span\u003e, \u003cspan class=\"postal-code\"\u003e93035-280\u003c/span\u003e, \u003cspan class=\"country-name\"\u003eBrazil\u003c/span\u003e",
      "formatted_address" : "Av. Padre Santini, 10 - Jardim America, São Leopoldo - RS, 93035-280, Brazil",
      "formatted_phone_number" : "(51) 3588-4411",
      "geometry" : {
         "location" : {
            "lat" : -29.7828115,
            "lng" : -51.125631
         },
         "viewport" : {
            "northeast" : {
               "lat" : -29.7814548697085,
               "lng" : -51.1243209697085
            },
            "southwest" : {
               "lat" : -29.78415283029149,
               "lng" : -51.1270189302915
            }
         }
      },
      "icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
      "id" : "e210f5742b71e37687d16c2c83b3aa8ee34aba3d",
      "international_phone_number" : "+55 51 3588-4411",
      "name" : "Cordoaria São Leopoldo",
      "opening_hours" : {
         "open_now" : false,
         "periods" : [
            {
               "close" : {
                  "day" : 1,
                  "time" : "1800"
               },
               "open" : {
                  "day" : 1,
                  "time" : "0730"
               }
            },
            {
               "close" : {
                  "day" : 2,
                  "time" : "1800"
               },
               "open" : {
                  "day" : 2,
                  "time" : "0730"
               }
            },
            {
               "close" : {
                  "day" : 3,
                  "time" : "1800"
               },
               "open" : {
                  "day" : 3,
                  "time" : "0730"
               }
            },
            {
               "close" : {
                  "day" : 4,
                  "time" : "1800"
               },
               "open" : {
                  "day" : 4,
                  "time" : "0730"
               }
            },
            {
               "close" : {
                  "day" : 5,
                  "time" : "1300"
               },
               "open" : {
                  "day" : 5,
                  "time" : "0730"
               }
            }
         ],
         "weekday_text" : [
            "Monday: 7:30 AM – 6:00 PM",
            "Tuesday: 7:30 AM – 6:00 PM",
            "Wednesday: 7:30 AM – 6:00 PM",
            "Thursday: 7:30 AM – 6:00 PM",
            "Friday: 7:30 AM – 1:00 PM",
            "Saturday: Closed",
            "Sunday: Closed"
         ]
      },
      "photos" : [
         {
            "height" : 4128,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/108991705824884881816/photos\"\u003ePISOS LAMINADOS\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAAM095blfyk5OxPChfdEee6IrF_BlCwb_d0sZgU0ocBOta23gu36ilzv45cvAFiREMP5KNxquCc8fvYEJPpIzq0Ov15l3_Nvh6HwmL-y5u1fMcXWoVmWMksrJbFCqhYzGZEhBuC-8VA5sNpe9OyXr4SENIGhSTo6qjN3EYqmV1JhlZQt_8dbnUTw",
            "width" : 2322
         }
      ],
      "place_id" : "ChIJ49bv_6lpGZURk4Hl8w31LRQ",
      "plus_code" : {
         "compound_code" : "6V8F+VP São Leopoldo, State of Rio Grande do Sul, Brazil",
         "global_code" : "582C6V8F+VP"
      },
      "rating" : 4.2,
      "reference" : "ChIJ49bv_6lpGZURk4Hl8w31LRQ",
      "reviews" : [
         {
            "author_name" : "Isaías Campos",
            "author_url" : "https://www.google.com/maps/contrib/102714935576413122283/reviews",
            "language" : "pt",
            "profile_photo_url" : "https://lh6.googleusercontent.com/-PorBdnT8hWU/AAAAAAAAAAI/AAAAAAAAABs/4IwNQqXvBV4/s128-c0x00000000-cc-rp-mo/photo.jpg",
            "rating" : 5,
            "relative_time_description" : "a year ago",
            "text" : "Lugar com segurança,e promove a mesma aos clientes, pessoas agradáveis,e o atendimento ótimo. ",
            "time" : 1498601517
         },
         {
            "author_name" : "Cristiana Roseli",
            "author_url" : "https://www.google.com/maps/contrib/112730753282117419678/reviews",
            "language" : "pt",
            "profile_photo_url" : "https://lh4.googleusercontent.com/-JWM4X8ZBeiw/AAAAAAAAAAI/AAAAAAAAAAA/ABtNlbDmCkeuXnzP3ijjziLnUF4X7fEBAQ/s128-c0x00000000-cc-rp-mo/photo.jpg",
            "rating" : 5,
            "relative_time_description" : "4 years ago",
            "text" : "fui funcionária da empresa cordoaria e tive o maior prazer em colaborar na produção de cabos e cordas .trabalhei apenas dois anos ,mas todos os dias que colaborei foi com imenso prazer por saber que é uma empresa de qualidade. uma verdadeira família ,juntos pelo mesmo objetivo: sempre fazer com que a cordoaria seja a referencia em tudo que produz. obrigada pela oportunidade e que cada dia seja de sucesso e prosperidade!  abraços ! CRISTIANA FREITAS",
            "time" : 1385663486
         },
         {
            "author_name" : "Alexandre Voese",
            "author_url" : "https://www.google.com/maps/contrib/103847514278555760957/reviews",
            "language" : "pt",
            "profile_photo_url" : "https://lh4.googleusercontent.com/-C0pc4NWTUWo/AAAAAAAAAAI/AAAAAAAAAB8/pgsnwrg6sPI/s128-c0x00000000-cc-rp-mo-ba4/photo.jpg",
            "rating" : 5,
            "relative_time_description" : "a year ago",
            "text" : "Otimo , porem o espaço é um pouco pequeno",
            "time" : 1482523930
         },
         {
            "author_name" : "Joao Vitor Ferraz",
            "author_url" : "https://www.google.com/maps/contrib/105277596827941636339/reviews",
            "language" : "pt",
            "profile_photo_url" : "https://lh4.googleusercontent.com/-_URdT97HheM/AAAAAAAAAAI/AAAAAAAAT-8/WSvZMBCBgPo/s128-c0x00000000-cc-rp-mo/photo.jpg",
            "rating" : 5,
            "relative_time_description" : "a year ago",
            "text" : "Bom\n",
            "time" : 1489669563
         },
         {
            "author_name" : "Cleber Aguilhera Prusch",
            "author_url" : "https://www.google.com/maps/contrib/111913700410068395411/reviews",
            "profile_photo_url" : "https://lh5.googleusercontent.com/-I0UgUbchFNA/AAAAAAAAAAI/AAAAAAAALA0/prcvFWMLAeY/s128-c0x00000000-cc-rp-mo/photo.jpg",
            "rating" : 1,
            "relative_time_description" : "a month ago",
            "text" : "",
            "time" : 1537310447
         }
      ],
      "scope" : "GOOGLE",
      "types" : [ "point_of_interest", "establishment" ],
      "url" : "https://maps.google.com/?cid=1454087694985822611",
      "utc_offset" : -180,
      "vicinity" : "Avenida Padre Santini, 10 - Jardim America, São Leopoldo",
      "website" : "http://www.csl.com.br/"
   },
   "status" : "OK"
}

我用 Google 表格构建的第一个查询(这里是一个例子:https://docs.google.com/spreadsheets/d/1w-dw82S23J-EVl1JHOS1ymhqxTNS5j2c5woFLEVqgAY/edit#gid=0)。

我的困难是再次获取地点 ID 和 运行 查询,所以我使用脚本编辑器。我基于这个 post 来构建我的脚本:https://matthewbilyeu.com/blog/using-the-google-places-api-in-google-sheets/

因为我在 sheet 秒内创建查询,所以我不需要使用 function locUrlToQueryUrl(locationUrl),我需要 运行 GET_LOC 使用我的queryUrl 作为输入并将数据发送到我的 sheet。我现在正在使用这段代码:

我对JavaScript不是很熟悉,所以对我来说不是很简单。下面的代码是我到现在为止所得到的,但它并没有把我需要的数据带回我的sheet。

function GET_LOC(queryUrl) {
  if (queryUrl == '') {
    return 'Give me a Google Places queryURL...';
  }

  var response = UrlFetchApp.fetch(queryUrl);
  var json = response.getContentText();
  var place = JSON.parse(json).results[0];
  var place_types = place.types.join(", ");


  return [[ place.name,
            place.formatted_address,
            place_types,
            place.rating,
            ]];
}

在我的 Google 表格中 运行: GET_LOC(<a href="https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=cordoaria%20sao%20leopoldo%brasil&inputtype=textquery&key=AI" rel="nofollow noreferrer">https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=cordoaria%20sao%20leopoldo%brasil&inputtype=textquery&key=AI</a>**) 我得到了#错误

编辑

奇怪的是我遇到了两种类型的错误。

当我运行 GET_LOC(https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=cordoaria%20sao%20leopoldo%brasil&inputtype=textquery&key=AI**)

我得到:

Erro
Argumento inválido: (*Translation: Invalid argument)
https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=cordoaria%20sao%20leopoldo%brasil&inputtype=textquery&key=AI** (linha 6).

当我运行 https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=INSTRUVAL%20INSTRUMENTOS%20E%20SERVICOS%20LTDA%20SAO%20CAETANO%20DO%20SUL%20SP%20&inputtype=textquery&key=AI**

我得到:

Erro
TypeError: Não é possível ler a propriedade "types" de undefined. (linha 9).
(*Translation: TypeError: Not possible to read types property in undefined)

问题不是我的 result/results

请检查此 google 张 [已删除 link,因为它不再存在]

项目代码就是下面这个(我很快就会删除我的密钥)

function locUrlToQueryUrl(locationUrl) {
  var API_KEY = 'AIXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
  var matches = locationUrl.match(/maps\/place\/(.*)\/@(.*),/);
  var name = matches[1];
  var latLon = matches[2];
  var baseUrl = 'https://maps.googleapis.com/maps/api/place/textsearch/json';
  var queryUrl = baseUrl + '?query=' + name + '&location=' +  latLon + '&radius=500&key=' + API_KEY;
  return queryUrl;
}


function GET_LOC(locationUrl) {
  if (locationUrl == '') {
    return 'Give me a Google Places URL...';
  }
  var queryUrl = locUrlToQueryUrl(locationUrl);
  var response = UrlFetchApp.fetch(queryUrl);
  var json = response.getContentText();
  var place = JSON.parse(json).results[0];
  var place_types = place.types.join(", ");
  var price_level = [];
  for (var i = 0; i < place.price_level; i++) { price_level.push('$'); }
  price_level = price_level.join('')

  return [[ place.name,
            place.formatted_address,
            place_types,
            place.rating,
            price_level ]];
}

我认为这里的主要内容是在单元格 A1 中你必须有一个 GOOGLE 地图 URL。意思是,当你点击 google 地图中的某个地方时得到的任何 url。

如果这对您有任何帮助,请告诉我。

Google sheets 和 Appscript 是很好用的产品,不要因为小缺点而气馁。

又是我。我再次查看了你的问题,我想我更好地理解你想做什么......你想在 google 工作表的单元格中输入文本,使用文本搜索 API 来检索地点 ID ,然后使用地点 API 检索有关该特定 ID

的数据

请查看此工作表 [已删除 link,因为它不再存在]

在单元格 B2 中,我们检索位置 ID,在单元格 c2 中,我们从 google 个位置检索字段 API。

下面还有宏代码

function locId(text) {
  var API_KEY = 'AIXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
  var baseUrl = 'https://maps.googleapis.com/maps/api/place/findplacefromtext/json';
  var queryUrl = baseUrl + '?input=' + text + '&inputtype=textquery&key=' + API_KEY;
  var response = UrlFetchApp.fetch(queryUrl);
  var json = response.getContentText();
  var placeId = JSON.parse(json);
  return placeId.candidates[0].place_id;
}


function GET_DETAILS(id) {
  var API_KEY = 'AIXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
  var fields = 'name,rating,formatted_phone_number,formatted_address,photo';
  var baseUrl = 'https://maps.googleapis.com/maps/api/place/details/json?placeid=';
  var queryUrl = baseUrl + id + '&fields=' + fields + '&key='+ API_KEY;

  if (id == '') {
    return 'Give me a Google Places URL...';
  }

  var response = UrlFetchApp.fetch(queryUrl);
  var json = response.getContentText();
  var place = JSON.parse(json).result;

  return [[ place.name,
            place.formatted_phone_number,
            place.rating,
            place.formatted_address,
           place.photo
          ]];
}

请注意,您可以在此处找到所有可用字段的完整列表,https://developers.google.com/places/web-service/details#fields,您可以将它们添加到宏代码中(我认为您足够聪明,知道在哪里)

不要忘记将 API 密钥替换为您自己的密钥。