如何从Google Maps URL获取Google Place ID (placeId)

4
我正在处理一个网站,用户可以为列表添加额外的链接。我正在尝试设置这样一个功能:当用户添加一个指向Google上的位置的链接时(例如从Google Maps获取共享链接:https://www.google.com/maps/place/Twin+Elephant+Brewing+Company/@40.7290336,-74.3828372,17z/data=!4m5!3m4!1s0x89c3afa1b597fe49:0x890cb024fe77e7b6!8m2!3d40.7290336!4d-74.3806485),我可以使用Google Places API来获取其他信息。
然而,Google Places API需要您指定地点ID,我想知道是否有一种方法可以从提供的地图URL中获取它?我知道您可以手动从这里获取:https://developers.google.com/maps/documentation/javascript/examples/places-placeid-finder但是否有一种通过地图URL获取Place ID的方法?
谢谢!
4个回答

3

可能有点晚了,但我想试一试...

背景信息:

这个答案建议您通过将地方的cid(不是placeId)传递给Places API Web Service来获取地方详情。

这利用了一个未记录的查询参数,因此使用它存在风险。这可能随时停止工作而没有警告!

这篇文章建议您可以从地图URL中提取cid

然后我找到了这段代码片段,帮助解析Google Maps URL中的data属性。

不幸的是,您不能使用AJAX调用使用Places API Web Service,因为您将遇到CORS问题,因此您需要使用另一种方法。您也不能使用Google Maps Javascript API的Places Library,因为它要求您传递placeId,并且不会接受cid。这就是为什么我必须使用PHP从Web服务中抓取结果的原因。

要运行下面的代码,您还需要jQuery,或者您需要替换$.ajax(...)函数,并且需要在Web服务请求(PHP代码)中替换<your_api_key>为您自己的API密钥。

所以我们开始吧...这是Javascript:

function mapsUrlToPlaceDetails(url) {

    var re = /data=(.*)/;

    var data = url.match(re);

    var str = data[1];

    var parts = str.split('!').filter(function (s) {
            return s.length > 0;
        }),
        root = [], // Root elemet
        curr = root, // Current array element being appended to
        m_stack = [root,], // Stack of "m" elements
        m_count = [parts.length,]; // Number of elements to put under each level

    parts.forEach(function (el) {

        var m = /^(\d+)(\w)(.*)$/.exec(el),
            idx = m[1],
            kind = m[2],
            value = m[3];

        // Decrement all the m_counts
        for (var i = 0; i < m_count.length; i++) {
            m_count[i]--;
        }

        if (kind === 'm') { // Add a new array to capture coming values
            var new_arr = [];
            m_count.push(value);
            curr.push(new_arr);
            m_stack.push(new_arr);
            curr = new_arr;
        } else {
            if (kind == 'b') { // Assuming these are boolean
                curr.push(value == '1');
            } else if (kind == 'd' || kind == 'f') { // Float or double
                curr.push(parseFloat(value));
            } else if (kind == 'i' || kind == 'u' || kind == 'e') { // Integer, unsigned or enum as int
                curr.push(parseInt(value));
            } else { // Store anything else as a string
                curr.push(value);
            }
        }

        // Pop off all the arrays that have their values already
        while (m_count[m_count.length - 1] === 0) {
            m_stack.pop();
            m_count.pop();
            curr = m_stack[m_stack.length - 1];
        }
    });

    var enc = root[0][0][0];

    // Find the CID with a regex
    re = /:0x(.*)/;
    var cMatch = enc.match(re);

    // We have the place CID as hexadecimal, we convert it to decimal in our PHP script
    var cid = cMatch[1];

    var serviceData = false;

    // Query our PHP page with our CID
    $.ajax({
        type: 'GET',
        url: 'get_place_details.php',
        data: {
            cid: cid
        },
        success: function (data) {

            if (data) {

                serviceData = data;
            }
        },
        async: false,
        contentType: "application/json",
        dataType: 'json',
    });

    return serviceData;
}

var url = 'https://www.google.com/maps/place/Twin+Elephant+Brewing+Company/@40.7290336,-74.3828372,17z/data=!4m5!3m4!1s0x89c3afa1b597fe49:0x890cb024fe77e7b6!8m2!3d40.7290336!4d-74.3806485';

console.log(mapsUrlToPlaceDetails(url));

这里是get_place_details.php页面:

<?php
header('Content-Type: application/json');

// Get the hexadecimal CID
$hexString = $_GET['cid'];

// Convert it to decimal
$decString = bchexdec($hexString);

// Query the web service
$url = 'https://maps.googleapis.com/maps/api/place/details/json?cid=' . $decString . '&key=<your_api_key>';
$json = file_get_contents($url);

// Print results
print $json;

// Convert hexadecimal CID to decimal
function bchexdec($hex) {

  $len = strlen($hex);
  for ($i = 1; $i <= $len; $i++)
    $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));

  return $dec;
}

以下是来自您问题中的示例URL的输出结果:
{
   "html_attributions" : [],
   "result" : {
      "address_components" : [
         {
            "long_name" : "13",
            "short_name" : "13",
            "types" : [ "street_number" ]
         },
         {
            "long_name" : "Watchung Avenue",
            "short_name" : "Watchung Ave",
            "types" : [ "route" ]
         },
         {
            "long_name" : "Chatham",
            "short_name" : "Chatham",
            "types" : [ "locality", "political" ]
         },
         {
            "long_name" : "Morris County",
            "short_name" : "Morris County",
            "types" : [ "administrative_area_level_2", "political" ]
         },
         {
            "long_name" : "New Jersey",
            "short_name" : "NJ",
            "types" : [ "administrative_area_level_1", "political" ]
         },
         {
            "long_name" : "United States",
            "short_name" : "US",
            "types" : [ "country", "political" ]
         },
         {
            "long_name" : "07928",
            "short_name" : "07928",
            "types" : [ "postal_code" ]
         }
      ],
      "adr_address" : "\u003cspan class=\"street-address\"\u003e13 Watchung Ave\u003c/span\u003e, \u003cspan class=\"locality\"\u003eChatham\u003c/span\u003e, \u003cspan class=\"region\"\u003eNJ\u003c/span\u003e \u003cspan class=\"postal-code\"\u003e07928\u003c/span\u003e, \u003cspan class=\"country-name\"\u003eUSA\u003c/span\u003e",
      "formatted_address" : "13 Watchung Ave, Chatham, NJ 07928, USA",
      "formatted_phone_number" : "(973) 507-9862",
      "geometry" : {
         "location" : {
            "lat" : 40.7290336,
            "lng" : -74.38064849999999
         },
         "viewport" : {
            "northeast" : {
               "lat" : 40.7305861302915,
               "lng" : -74.37907051970849
            },
            "southwest" : {
               "lat" : 40.7278881697085,
               "lng" : -74.3817684802915
            }
         }
      },
      "icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
      "id" : "033d042f48225906fe15f77f5b3a3e7b6aeeab89",
      "international_phone_number" : "+1 973-507-9862",
      "name" : "Twin Elephant Brewing Company",
      "opening_hours" : {
         "open_now" : false,
         "periods" : [
            {
               "close" : {
                  "day" : 4,
                  "time" : "2100"
               },
               "open" : {
                  "day" : 4,
                  "time" : "1600"
               }
            },
            {
               "close" : {
                  "day" : 5,
                  "time" : "2200"
               },
               "open" : {
                  "day" : 5,
                  "time" : "1600"
               }
            },
            {
               "close" : {
                  "day" : 6,
                  "time" : "2200"
               },
               "open" : {
                  "day" : 6,
                  "time" : "1200"
               }
            }
         ],
         "weekday_text" : [
            "Monday: Closed",
            "Tuesday: Closed",
            "Wednesday: Closed",
            "Thursday: 4:00 – 9:00 PM",
            "Friday: 4:00 – 10:00 PM",
            "Saturday: 12:00 – 10:00 PM",
            "Sunday: Closed"
         ]
      },
      "photos" : [
         {
            "height" : 2448,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/116322776679362173973/photos\"\u003eJohn Cisco\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAA5OjbmTwkvKGIODbDIq7iqRmY936SHMmM8Lp-ao-tZz9TjysnV1iLo8TU7c3vaOqKEEFp9sjgdQXaryTXmkayEgbRf1R_kHTUMALncnIbJgUUNWUQfVZZZFYwAVSNT3xrEhBoDze6Deo-OY-R4QBsJSGUGhRBTr8UU62fuUe7uQ8GC_eGZVy-0Q",
            "width" : 3264
         },
         {
            "height" : 640,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/108115407768700900550/photos\"\u003eTwin Elephant Brewing Company\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAAkseOCiYmA_QuZtUtpLL32udgqGJHWUxmQPH646Ml16SjCwRv1gS-ynYkWM5n54m36S2uUstVZ0ld4nDlosYblDeQxvq8_KxRrVyKtavY8cQvY9l2cidOWgF7XBYKVzSMEhDO3A3SJPio3XhenCtDgkhUGhTDMYIMOvpFmkQXy4dMYQD19-_VkQ",
            "width" : 480
         },
         {
            "height" : 1080,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/105468313205986835052/photos\"\u003eU. Minocha\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAAFY3e-92GOB5gZ02gRnRisBWhqIr-_bCxDhNff5kYX7XRtcDY-3Q4d1eRN71fouXOJWQH02EUXXmsDaSk9nw91ajUMjdZXdUdgnWsLtWci_QwBmTs604TDtD9IBOUgdsGEhDGUo8VR6VxAz5dn58v2K5EGhTyypm6Z3dw8VRo7ARzeY0B33jpHA",
            "width" : 1920
         },
         {
            "height" : 2988,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/106472583958367361068/photos\"\u003eSteven Grillo\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAA_toJLI4dqBnPcYWU3xcg74OTOguLrFcYuobfrefJKzMI1YvzLC5su3qG5ePhwwCNPhbuf2yRrf1xAwNyb786f9W6SUcPqm1Ixys7kdtLRtq2PCGGR7uJPNy7diIxltAFEhDJ1iv7zV9Wy-L2LmMK6awaGhS8lS-vGVLbyuoBvnLUHMoo7G9P-g",
            "width" : 5312
         },
         {
            "height" : 3024,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/102366024100729755902/photos\"\u003eGiri Sonty\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAAxUDQSpdmVLqwEhkmglkZCgHrgF8pu5fQuEwQqJGdPX-LF4HFfVTW3P-sCORrFZToktnujwI5_qsC6s7lYbdaXt3-zyUZ5Y1cG-Qsf8iyPdfLFKbmqzQYePDyESBbotZKEhDkJqPi01x3SBsMfB9F7ozpGhSuBaRTN8WuFjKLFnhHmQBBhjCpFg",
            "width" : 4032
         },
         {
            "height" : 1920,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/105155780654274802017/photos\"\u003eTim Besecker\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAAnYSYhIWKK5g6iw5YuE3W6rcrcsMjLkkAh7WOwrK7byCBH5mXOVEukvboWIEBR_03igd52Nv2j65HkaOZtqEOt5wIg_-jUxyGUoiYWSgx5lE0Bfr7lfr_hLIL0F1Ih5QgEhC2T7UwbXzWyMntI1hjYwimGhQuwFneOqYQFlkXRVk2djZMH8MukQ",
            "width" : 1536
         },
         {
            "height" : 4048,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/111388773475383063875/photos\"\u003eChris Bryant\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAALgkt5N4lbOd9KKbodX6e85cr53AMmTCHtUcpY4A8GstXaYQ0A3ZxVy3HidMeRsq6ttB335aY3caGghlzlGn6ZKTh3UYqhBIWDEtbAP55Sfmn_ejguBmUwXGvYPXwXnJ0EhAMxT0nVxswsz3t4vKMXNYlGhS61J6w9kwPE78p48JziVu6BuXpOQ",
            "width" : 3036
         },
         {
            "height" : 3904,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/113301757065540994941/photos\"\u003eBrian Davies\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAAwBpwY85PAJA8kMCwHfFa5AjfKhWKt9tWr24dW4c3jg7OKgem6Fiy3ujkgJn3I2qjdnhaQ_doPoh7nOFC3pMyk0lhg3PBrEmlV4I-WV_b-ijbSCyNsc6XSgWCa33lJCrVEhCiuzN8SVwykAsKYnaqr5wyGhRBmlmH4UF3sli--wgW3NFt-JCnaQ",
            "width" : 2928
         },
         {
            "height" : 3006,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/104479106479135628391/photos\"\u003eMark Burgos\u003c/a\u003e"
            ],
            "photo_reference" : "CmRaAAAA_eEr3xWGNj_0Z9ZV7kCtLoShbGyV_Lm7fWPgqzoI-XkZDXEpKN6lyEka5DdbHPa_UKCZFJc2NHqcCHcO2wqohW5kOgev6KJBPowo-dwzweebBOHqjHYOIDTzCuNI-e3JEhDlQWANhY1vjamISDqmerQDGhSyKw-BY2sF2z2PJVP5Ebxn4XyUOw",
            "width" : 4442
         },
         {
            "height" : 2160,
            "html_attributions" : [
               "\u003ca href=\"https://maps.google.com/maps/contrib/101684835260872241844/photos\"\u003eJohn Worobetz\u003c/a\u003e"
            ],
            "photo_reference" : "CmRZAAAAaxND_m7EEmb_H-AcjE11kV9TSpDNmqSp_yb9rvoeMfXli-YpkNl40ynUbFbIdBlvzQABml_g8QyVRVjO1xX_22tLDGC2BjRYjUVU2jSQ3lh8vpBQXpVS-QqgsRiKs5MjEhDPSv331G9tFTL4i9ZRxrTtGhQiu6Y77QuIF-yDjC5K7l03RHX0RQ",
            "width" : 2880
         }
      ],
      "place_id" : "ChIJSf6XtaGvw4kRtud3_iSwDIk",
      "rating" : 4.6,
      "reference" : "CmRSAAAA81Dn88T7QUFqgafk6p_RmBF2QwxF4ciZ1RiAl2FX_FnH_6V8xhBut-wwn55PA5RqzR1lnASt8IU220bIcnhK-X5LaOZfiRA-Ev4xqFIwD_5Bih40Zp0_r90rujcd0aDtEhBmmicu6C2zft-mfZaKRM44GhS9vO5jT0yZ21uPyvkNkU47rrHSUQ",
      "reviews" : [
         {
            "author_name" : "Chris Hall",
            "author_url" : "https://www.google.com/maps/contrib/105472690796059859093/reviews",
            "language" : "en",
            "profile_photo_url" : "https://lh6.googleusercontent.com/-c2FE0ic_69g/AAAAAAAAAAI/AAAAAAAAAJE/JkiTdWGipz8/s128-c0x00000000-cc-rp-mo-ba2/photo.jpg",
            "rating" : 5,
            "relative_time_description" : "a month ago",
            "text" : "Great local brewery with a great selection of beers. The outdoor, indoor decor gives it a great vibe and is a happening place for families and friends of all (legal) ages. I wold definitely recommend the flight tasters. Only one downfall, they're always out of growlers, so I never get to take my favorite taster home. Great spot overall!",
            "time" : 1522938350
         },
         {
            "author_name" : "U. Minocha",
            "author_url" : "https://www.google.com/maps/contrib/105468313205986835052/reviews",
            "language" : "en",
            "profile_photo_url" : "https://lh5.googleusercontent.com/-DvbLy6Lfe1Y/AAAAAAAAAAI/AAAAAAAAcok/XtWUnfo600c/s128-c0x00000000-cc-rp-mo-ba5/photo.jpg",
            "rating" : 4,
            "relative_time_description" : "2 months ago",
            "text" : "Place is hard to find and parking is limited but worth it. They have 3 oz 5-beer flights, 8 and 16 oz pours. Good beers - different styles; not a mono-style place. Place was packed at 3:30 pm on Sat afternoon  (imagine that) but the lines move quick and staff is friendly. Great rustic decor.",
            "time" : 1518901110
         },
         {
            "author_name" : "Chris D'Anna",
            "author_url" : "https://www.google.com/maps/contrib/109252609008737722129/reviews",
            "language" : "en",
            "profile_photo_url" : "https://lh6.googleusercontent.com/-XoBlrw7wJN4/AAAAAAAAAAI/AAAAAAAAFhk/ksUvusFcOk8/s128-c0x00000000-cc-rp-mo-ba3/photo.jpg",
            "rating" : 5,
            "relative_time_description" : "3 weeks ago",
            "text" : "Great fast service and very knowledgeable. And the beer was delicious. My favorite part is they offer many for takeout growler. I will definitely be back very soon.",
            "time" : 1524017924
         },
         {
            "author_name" : "Eric Larsen Larsen",
            "author_url" : "https://www.google.com/maps/contrib/104887350051046383743/reviews",
            "language" : "en",
            "profile_photo_url" : "https://lh3.googleusercontent.com/-EH-6GOaD73U/AAAAAAAAAAI/AAAAAAAAAAA/AIcfdXA8ntBCFqZ6ozlr3xDuN5In7Gemmg/s128-c0x00000000-cc-rp-mo/photo.jpg",
            "rating" : 5,
            "relative_time_description" : "a week ago",
            "text" : "I have been stopping in for 9 months now. Awesome employees. Great Beer and descent selection. My favorite to date Weepel and Lil Shimmy",
            "time" : 1525543191
         },
         {
            "author_name" : "Pete Antoniewicz",
            "author_url" : "https://www.google.com/maps/contrib/108718838193824181246/reviews",
            "language" : "en",
            "profile_photo_url" : "https://lh4.googleusercontent.com/-59_xOCRQPDI/AAAAAAAAAAI/AAAAAAAAAAA/l-PiY85YX5g/s128-c0x00000000-cc-rp-mo-ba5/photo.jpg",
            "rating" : 3,
            "relative_time_description" : "2 months ago",
            "text" : "Nice place, beers ok.  A little crowded though there was a big birthday party taking up a lot of room.  Garbage cans right by the entrance.  Hopefully working out the kinks.  A great addition to the area.",
            "time" : 1520108642
         }
      ],
      "scope" : "GOOGLE",
      "types" : [ "food", "point_of_interest", "establishment" ],
      "url" : "https://maps.google.com/?cid=9875461755851237302",
      "utc_offset" : -240,
      "vicinity" : "13 Watchung Avenue, Chatham",
      "website" : "http://www.twinelephant.com/"
   },
   "status" : "OK"
}

希望这能帮到你,但是要注意:自行承担风险!

2

您无法从URL中获取place_id,您提到的placeid查找器实际上是一个应用程序,它使用GM Javascript API的自动完成服务来获取它们。

解决方法是从URL获取坐标(这可以做到),然后使用自动完成服务或地理编码器获取place_id(从URL获取的坐标)。


-1

虽然已经过去了3年,但我仍想分享我的解决方案。

对我来说,最好的解决方法是使用已经指定地点的Google Maps URL。这需要两个步骤。

  1. 从URL字符串中提取位于“/maps/place/”和“@”之间的地名。
  2. 使用Google地点文本搜索搜索提取出的地名。“查询”中输入“query”,如此处所述,您将获得该地点的详细信息,包括place_id。

-1
curl -X POST 'https://ruriazzfree.vercel.app/api/scrape/gplace' \
     -H 'Content-Type: application/json' \
     -d '{"gmap_link": "https://goo.gl/maps/DMMAakiA6nZrq9TE7"}'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接