Python调用API时POST请求返回400错误,求可行解决方案
问题解决思路
为什么POST请求返回400错误?
- JSON格式错误:你写的
data字符串转义符混乱,不是有效的JSON格式,API无法解析。 - 签名过期:
x-halo-signature里的时间戳t=1701286548是旧的,这个签名是网站实时生成的,过期后会被API拒绝。
可行解决方案
方案1:修复POST请求(需实时获取签名)
先修正JSON数据格式,再从浏览器抓包获取最新的签名(因为签名无法逆向生成,只能临时用抓包的有效签名测试):
import pandas as pd import requests headers = { 'authority': 'api.halotechnologies.com.au', 'accept': '*/*', 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8', 'content-type': 'application/json', 'origin': 'https://www.halo-technologies.com', 'referer': 'https://www.halo-technologies.com/markets/shares/asx/PLS', 'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'cross-site', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', # 替换成浏览器抓包得到的最新签名 'x-halo-signature': 't=最新时间戳,s=最新签名串', } # 正确的JSON数据结构 data = { "countryCode": "AU", "security": "PLS", "components": "shortSell" } # 用json参数传递数据,requests会自动处理格式和编码 response = requests.post( 'https://api.halotechnologies.com.au/api/security/quote/public', headers=headers, json=data ) # 解析响应并转成DataFrame if response.status_code == 200: result = response.json() df = pd.DataFrame(result['shortSell']) print(df) else: print(f"请求失败,状态码:{response.status_code}")
方案2:用Selenium模拟浏览器抓取(更适合新手)
签名机制复杂,直接模拟浏览器加载页面提取数据,无需处理API验证:
import pandas as pd 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 import time # 初始化Chrome浏览器(需提前下载对应版本的chromedriver) driver = webdriver.Chrome() driver.get('https://www.halo-technologies.com/markets/shares/asx/PLS') # 等待页面加载卖空数据(显式等待更可靠) wait = WebDriverWait(driver, 10) table = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'table[data-testid="short-sell-table"]'))) # 提取表格行数据 rows = table.find_elements(By.TAG_NAME, 'tr') short_sell_data = [] # 跳过表头行,遍历数据行 for row in rows[1:]: cols = row.find_elements(By.TAG_NAME, 'td') if cols: short_sell_data.append({ '日期': cols[0].text, '卖空成交量': cols[1].text, '卖空占比': cols[2].text, '总成交量': cols[3].text }) # 转成DataFrame查看 df = pd.DataFrame(short_sell_data) print(df) # 关闭浏览器 driver.quit()
注意:使用Selenium需要下载对应浏览器的驱动程序(如Chrome的chromedriver),版本要和浏览器一致。
内容的提问来源于stack exchange,提问作者KRT
相关产品推荐
相关产品推荐

