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

Python Requests认证问题:Hertz API爬虫Cookie设置异常求助

问题

尝试爬取Hertz租车API(请求URL:https://www.hertz.com/rentacar/rest/hertz/v2/itinerary/vehicles)获取特定行程定价,该API不在robots.txt禁止列表中。已从浏览器捕获提交行程详情时的payload,使用该payload、含dtm_token和User-Agent的请求头、访问Hertz主页获取的Cookie调用API,虽得到200响应,但未返回预期结果;仅用token不带Cookie则触发Incapsula机器人检测。判断是Cookie获取方式无效,寻求技术指导。

相关代码

import requests
import time

#URL 1 utilized to hit Hertz page and ideally return cookies to do API query with URL 2
url1="https://www.hertz.com"

url2="https://www.hertz.com/rentacar/rest/hertz/v2/itinerary/vehicles"

headers={"dtm_token":"HereIsAfakeTokenforAnExample",
          'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}

#Payload copied from browser when performing the request from Hertz's homepage with trip details (location, dates, times)
#This payload is what is submitted by your browser when making a request to book a rental via URL2
params={'lastName': '', 'resSearch': False, 'showRentalAgreement': False, 'showEvRentalAgreement': False, 'goldAnytimeRes': False,
        'checkLIS': False, 'checkFPO': False, 'buttonLIS': False, 'buttonFPO': False, 'showBothElements': False,
        'cdpVerificationFailed': 0, 'forceResHomePage': '', 'href': '/rentacar/rest/home/form', 'confirmationNumber': '',
        'arrivingUpdate': '', 'defaultTab': '', 'militaryClock': 0, 'majorAirport': '', 'returnAtDifferentLocationCheckbox': '',
        'dropoffLocation': '', 'inpPickupAutoFill': 'Y', 'inpPickupStateCode': 'VA', 'inpPickupCountryCode': '', 'inpPickupSearchType': '3',
        'inpDropoffAutoFill': '', 'inpDropoffStateCode': '', 'inpDropoffCountryCode': '', 'inpDropoffSearchType': '', 'pickupHiddenEOAG': 'IADT26',
        'dropoffHiddenEOAG': '', 'memberOtherCdpField': '', 'cdpField': '', 'corporateRate': '', 'officialTravel': '',
        'pcNumber': '', 'typeInRateQuote': 'BEST', 'cvNumber': '', 'itNumber': '', 'originalRqCheckBox': '', 'checkDiscount': '',
        'affiliateMemberJoin': '', 'affiliateMemberID': '', 'affiliateCallCount': 0, 'hertzlinkActive': False, 'companyId': '',
        'pickupDay': '05/22/2024', 'pickupTime': '12:00', 'dropoffDay': '05/23/2024', 'dropoffTime': '12:00', 'no1ClubNumber': '',
        'selectedCarType': 'ACAR', 'ageSelector': '25', 'redeemPoints': '', 'fromLocationSearch': False,
        'recommendationBrowserInfo': {'appCodeName': 'Mozilla', 'appName': 'Netscape', 'appVersion':
                                      '5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
                                      'cookieEnabled': True, 'language': 'en-US', 'onLine': True, 'platform': 'MacIntel', 'product': 'Gecko',
                                      'userAgent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36', 'visitorId': ''},
        'pickupLocation': 'Washington Dulles International Airport', 'inpPickupIsServedBy': 'N', 'inpPickupHasSpecialInstruction': 'N',
        'pickupDayStandard': '2024/05/22', 'dropoffDayStandard': '2024/05/23', 'inpPickupOptGoldAnytime': '', 'memberSelectedCdp': '', 'cdpRadioButton': ''}

response1=requests.get(url1, headers=headers)

#introducing sleep to make this less machine-like
time.sleep(2)

#used for debugging
print(response1.status_code)
print(response1.cookies)

#API request to get rental options and pricing
response2=requests.get(url2, headers=headers, params=params, cookies=response1.cookies)

#used for debugging
print(response2.status_code)
print(response2.text)
print(response2.cookies)

终端输出

200
<RequestsCookieJar[]>
200
见下方85行响应片段
<RequestsCookieJar[]>

返回内容

您的浏览行为被判定为机器人,可能原因如下:

  • 浏览器禁用了JavaScript
  • 浏览速度过快
  • 浏览器禁用了Cookie
  • 第三方插件(如Ghostery、NoScript)阻止了JavaScript运行
    请启用Cookie和JavaScript后重新加载页面以恢复访问。

解决方案

1. 改用会话(Session)维持Cookie

requests的Session对象会自动处理Cookie的持久化,比单独获取主页Cookie更可靠。替换现有代码中的请求方式:

session = requests.Session()
session.headers.update(headers)
# 先访问主页初始化会话
response1 = session.get(url1)
time.sleep(2)
# 用会话发送API请求
response2 = session.get(url2, params=params)

2. 补充缺失的请求头字段

浏览器发送请求时会携带更多头信息,仅dtm_token和User-Agent不够,建议添加以下字段(从浏览器开发者工具中复制真实值):

  • Accept
  • Accept-Language
  • Accept-Encoding
  • Referer(设置为https://www.hertz.com/)
  • Origin(设置为https://www.hertz.com)

3. 处理JavaScript生成的Cookie

Hertz的反爬系统可能需要由JavaScript生成的Cookie(如Incapsula的验证Cookie),纯requests无法执行JS,可使用以下两种方式:

  • 使用Playwright渲染页面:这类工具能模拟浏览器执行JS,自动获取完整Cookie。示例代码:
    from playwright.sync_api import sync_playwright
    
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page(user_agent=headers['User-Agent'])
        page.goto(url1)
        time.sleep(3)
        # 获取所有Cookie并转换为requests可用格式
        cookies = {c['name']: c['value'] for c in page.context.cookies()}
        # 发送API请求
        response = requests.get(url2, headers=headers, params=params, cookies=cookies)
        browser.close()
    
  • 手动复制浏览器Cookie:在浏览器中完成初始访问后,从开发者工具的Application-Cookies中复制所有Cookie,直接传入requests.get的cookies参数。

4. 验证dtm_token的有效性

dtm_token是动态生成的,可能会过期或与会话绑定。确保使用的是从当前浏览器会话中获取的最新dtm_token,而非固定的假值。

5. 调整请求方式和参数顺序

检查浏览器开发者工具中的请求方法,确认API是否为POST而非GET。另外,参数的顺序可能被反爬系统校验,保持与浏览器捕获的参数顺序一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 16:09:54