是否可以触发 Google Maps api 的 JavaScript 点击监听器,然后通过 Python 抓取数据?

Posted

技术标签:

【中文标题】是否可以触发 Google Maps api 的 JavaScript 点击监听器,然后通过 Python 抓取数据?【英文标题】:Is it possible to trigger Google Maps api's JavaScript click listener then scrape the data via using Python? 【发布时间】:2022-01-03 13:10:12 【问题描述】:

http://ihe.istanbul/satis-noktalari

我想在使用 Google Maps api 的地图上抓取目标公司经销商的点 (latLng) 数据。

我尝试使用requests_html在网站页面上渲染javascript来抓取数据,然后我曾经使用BeautifulSoup到达元素。

from bs4 import BeautifulSoup
from requests_html import HTMLSession

# create an HTML Session object
session = HTMLSession()

# Use the object above to connect to needed webpage
resp = session.get("http://ihe.istanbul/satis-noktalari")

# Run JavaScript code on webpage
resp.html.render()

soup = BeautifulSoup(resp.html.html, "lxml")

html_content = soup.contents[1]

_script = html_content.find_all("script")[23]
print(_script)

因此,打印将我引导到一种方式,如果触发点击事件,我可以看到所需的区域,在那里我可以找到 latLng 点值。

但是,网站的 url 不能自行更新并为选定的城市区域添加标签。

为了清楚地解释我自己,我制作了两张图片来准确显示我想要做什么:

此输出显示没有选定城市的结果:

这是显示预期结果的触发点击事件:

如果可以在通过 Google Maps api 触发 JavaScript 事件后更新 url,我可以使用该 url。 如何使用 Python 触发它,或者如何使用 Python 抓取触发的数据?我提供的 Python 代码显示了非触发事件。

【问题讨论】:

【参考方案1】:

鉴于页面使用value 下拉列表中的选项value 属性值动态发出POST XHR 请求。您可以提取这些值,模仿 POST 请求页面,然后使用正则表达式从响应中提取 lat、lon。下面展示了获取中心指定坐标的逻辑。

import requests, re

headers = 
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Mozilla/5.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Referer': 'http://ihe.istanbul/satis-noktalari',
    'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8',


results = 

with requests.Session() as s:
    
    s.headers = headers
    r = s.get('http://ihe.istanbul/satis-noktalari')
    soup = bs(r.content, 'lxml')
    options = i.text:i['value'] for i in soup.select('[name=ilceID] option:nth-child(n+2)') 
    
    for k, v in options.items():

        data = 'ilceID': v, 'SatisBufe': '1'

        r = s.post('http://ihe.istanbul/satis-noktalari', data=data)
        
        lat, lon = re.search(r'google.maps.LatLng\(([\d.]+),\s?([\d.]+)\)', r.text).groups()
        
        print(k, f'lat = lat', f'lon = lon')
        
        results[k] = [lat, lon]

【讨论】:

以上是关于是否可以触发 Google Maps api 的 JavaScript 点击监听器,然后通过 Python 抓取数据?的主要内容,如果未能解决你的问题,请参考以下文章

Google Maps API v3:在Firefox中未触发自定义标记的点击事件

Google Maps - Autocomplete & Directions API - 触发下拉列表的 onchange()?

是否可以使用 Google Maps API 获取当前交通时间以获取精确路线?

向 Google Maps API InfoWindow 中的元素添加事件

Google Maps API 街道坐标

是否可以在Google Maps API v3上编写自定义文字?