You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用R抓取含表单及JS的网站:POST提交后仍获旧数据求助

解决动态JS生成内容的爬虫问题

嘿,这个问题我之前也碰到过不少——很多依赖JS渲染的网站,表面上是表单提交,但实际背后是通过AJAX调用后台API来获取数据,直接模拟表单POST肯定拿不到结果。针对你这个距离计算器网站,我给你两个可行的解决方案:

方法一:直接调用后台API(高效首选)

这个网站的Calculate按钮点击后,并没有把表单数据直接提交到服务器返回新页面,而是用JavaScript偷偷发了一个API请求去拿计算好的距离数据,再渲染到页面上。所以我们可以跳过前端页面,直接跟这个API打交道:

  1. 抓包找到真实API

    • 打开浏览器的开发者工具(按F12),切换到「Network」标签页。
    • 正常输入你要查询的两个城市,点击「Calculate」按钮,观察Network里的请求列表。你会看到一个新的请求(可能是POST或GET方法),它的响应内容就是距离相关的JSON数据。
    • 记下这个API的URL、请求方法(POST/GET)、需要的参数(比如from、to、units这些,可能是地点字符串或者经纬度),还有请求头里的必要信息(比如User-Agent,有些网站会校验这个)。
  2. 用爬虫直接请求API
    比如用Python的requests库,直接构造请求发送给这个API,就能拿到结构化的结果,不用处理复杂的页面渲染。举个简化的例子(具体参数要根据你抓包的结果调整):

    import requests
    
    url = "https://www.distancecalculator.net/api/your-found-api-endpoint"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
    }
    data = {
        "from": "Craíbas - AL, Brasil",
        "to": "Maceió - AL, Brasil",
        "units": "km"  # 假设单位参数是km
    }
    
    response = requests.post(url, headers=headers, data=data)
    result = response.json()
    print(f"距离:{result['distance']} {result['unit']}")
    

方法二:用无头浏览器模拟用户操作(稳定可靠)

如果抓API觉得麻烦,或者网站的API有反爬机制,那可以用无头浏览器(比如Selenium、Playwright)完全模拟真实用户的操作,让浏览器帮你执行JS并渲染出结果:

以Selenium为例,代码大概是这样的:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 启动无头Chrome(不会弹出浏览器窗口)
options = webdriver.ChromeOptions()
options.add_argument('--headless=new')
driver = webdriver.Chrome(options=options)

try:
    # 打开目标网站
    driver.get("https://www.distancecalculator.net/")
    
    # 填写出发地和目的地
    from_input = driver.find_element(By.ID, "from")
    from_input.send_keys("Craíbas - AL, Brasil")
    
    to_input = driver.find_element(By.ID, "to")
    to_input.send_keys("Maceió - AL, Brasil")
    
    # 点击Calculate按钮
    calculate_btn = driver.find_element(By.XPATH, '//button[contains(text(), "Calculate")]')
    calculate_btn.click()
    
    # 等待结果加载完成(最多等10秒)
    distance_result = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CLASS_NAME, "distance-number"))  # 这个类名要根据页面实际元素调整
    )
    
    print(f"计算结果:{distance_result.text}")
finally:
    # 关闭浏览器
    driver.quit()

注意事项

  • 方法一效率更高,适合批量爬取,但要注意API可能会随时变化(比如参数、URL),需要定期检查抓包结果。
  • 方法二更稳定,不容易触发反爬,但速度慢、消耗资源多,适合少量查询。
  • 不管用哪种方法,都要遵守网站的使用条款,不要频繁请求,避免被封禁IP。

内容的提问来源于stack exchange,提问作者Diego Rodrigues

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:08:35