Python请求Trulia GraphQL接口遇POST body missing错误求助
解决Python请求Trulia GraphQL时出现"POST body missing"错误
问题根源
请求失败有两个核心原因:
data字符串开头的${是curl的变量语法,转成Python时未清理,导致JSON格式完全无效,服务器无法解析请求体。- 虽然请求头设置了
content-type: application/json,但直接用data传递字符串时,若格式不合法,服务器会判定请求体缺失。
修复步骤及代码
- 清理curl残留的变量语法,改用Python字典定义请求体,避免手动拼接JSON的转义错误;
- 使用
requests.post的json参数替代data,让requests自动完成JSON序列化,确保请求格式符合要求。
修正后的代码:
import requests headers = { 'authority': 'www.trulia.com', 'accept': '*/*', 'accept-language': 'en-US,en;q=0.9', 'content-type': 'application/json', 'cookie': 'tlftmusr=220127r6dy3udjlwtjr01eae5y1am065; s_fid=506AFCB7DCC3B70E-04D45F7B245F2989; zjs_anonymous_id=%22220127r6dy3udjlwtjr01eae5y1am065%22; _pxvid=634490ac-7faf-11ec-97bb-46596545526e; s_vi=[CS]v1|30F97FF6092382A7-400009A2368190B5[CE]; __gads=ID=0eb268a112aea6f0:T=1643315195:S=ALNI_MaLaqYG67wdCJeuAFsdIERsHIa4-g; commute=0|6|true; zg_anonymous_id=%22cc042b2d-29ef-4e76-b308-28aeaff9a2e1%22; g_state={"i_l":0}; stpa=91bdcbde35bfe55ff02e350d14f75e445b42ea3e41f2e46a203989d356bff928; stpr=cdcff13428427b5ddb1781c5d4859c89c6acef163f2b209d1646a1120a69b9a0; _pbjs_userid_consent_data=3524755945110770; _lr_env_src_ats=true; pbjs_identitylink=AhQek2Yd4okYD6kzV87whVYRVpd5gpbKXI814m-bhzxpNhZkGc6-cA7a7IWQn4fqY6mRjIPp7V1HixTEIYOnwEGtdpg2T68gnHO19Y1hvTvGTuMisyzrA_C177JiSpHmkBQ6; _csrfSecret=chVcTCGkojJf4aCkyL4Tb9W3; pxcts=70ff9020-11bf-11ed-801e-724c78677a6a; s_cc=true; branch_banner_closed=true; QSI_S_ZN_aVrRbuAaSuA7FBz=v:0:0; _lr_geo_location=GB; _pxhd=nuRoQ8PYpvv5IFHZqpNRyclkZmK2j5vYVdTClh/G2Lm2h8FzsW243Ht4FF3PyNSfdSDFcidjR6Cjanayd0MKGw==:DzVg679PRtFcVxHRZ9FRr8BJYXUOKB-zxP6g6iFwwgaaancqb/io9qDdHLhAfFJF9/6CNgdM1pddBEnzcOYqc1oKFtTbU2RuB3CWbZA8rC8=; _lr_sampling_rate=100; __gpi=UID=0000044f4a7ee8c2:T=1649400644:RT=1660020564:S=ALNI_MYBilKp0qq4hojdg9AyNF4Fhe1OnA; trul_visitTimer=1660019642110_1660021418934; OptanonConsent=isIABGlobal=false&datestamp=Mon+Aug+08+2022+22%3A03%3A39+GMT-0700+(Pacific+Daylight+Time)&version=5.8.0&landingPath=NotLandingPage&groups=1%3A1%2C0_234869%3A1%2C3%3A1%2C4%3A1%2C0_234866%3A1%2C0_234867%3A1%2C0_234868%3A1%2C0_240782%3A1%2C0_240783%3A1%2C0_240780%3A1%2C0_234871%3A1%2C0_240781%3A1%2C0_234872%3A1%2C0_234873%3A1%2C0_234874%3A1%2C0_234875%3A1%2C0_234876%3A1%2C0_234877%3A1&AwaitingReconsent=false; zjs_user_id=%2259788808%22; s_sq=%5B%5BB%5D%5D', 'origin': 'https://www.trulia.com', 'referer': 'https://www.trulia.com/p/oh/bedford/59-john-st-bedford-oh-44146--1009668993', 'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', 'x-bc-buildercommunitydata': '1', 'x-contextual-highlights': '1', 'x-csrf-token': 'OccCsutt-ZVwpowv1P9gB9RCaSrqkPZ02WJg', 'x-papi-fall-back-disabled': '0', 'x-pdc-api-enabled': '0', 'x-rc-bls': '1', 'x-request-id': 'client-92d6a7c4-68c0-40ed-89e8-a267d4269e50', 'x-zg-search-enabled': '0', } params = ( ('opname', 'WEB_fetchAffordabilityQuery'), ('transactionId', 'client-92d6a7c4-68c0-40ed-89e8-a267d4269e50'), ) # 用Python字典定义请求体,避免手动拼接JSON的格式错误 payload = { "operationName": "WEB_fetchAffordabilityQuery", "variables": {"url": "/p/oh/bedford/59-john-st-bedford-oh-44146--1009668993"}, "query": """query WEB_fetchAffordabilityQuery($url: String!) { homeDetailsByUrl(url: $url) { ... on HOME_Details { ...HomeDetailsMortgageInfoAndHoaFeeFragment location { city stateCode zipCode __typename } price { ... on HOME_ValuationPrice { price __typename } ... on HOME_LastSoldPrice { price __typename } ... on HOME_SinglePrice { price __typename } __typename } metadata { compositeId __typename } __typename } __typename } } fragment HomeDetailsMortgageInfoFragment on HOME_MortgageInfo { ctaUrls { purchaseRates postLead __typename } mortgageInquiryCta(useRefinancePreQualifyLink: true) { text url __typename } rates { defaultRates { taxRate interestRate __typename } taxRate interestRates(creditScore: EXCELLENT) { loanDuration rate creditScore displayName loanType __typename } __typename } defaults { homePrice { price __typename } loanDuration downPaymentPercentage insurance { price __typename } __typename } mortgageEstimateDisclaimer __typename } fragment HomeDetailsHoaFeeFragment on HOME_HoaFee { period amount { price __typename } __typename } fragment HomeDetailsMortgageInfoAndHoaFeeFragment on HOME_Details { ... on HOME_Property { hoaFee { ...HomeDetailsHoaFeeFragment __typename } mortgageInfo { ...HomeDetailsMortgageInfoFragment __typename } __typename } ... on HOME_FloorPlan { hoaFee { ...HomeDetailsHoaFeeFragment __typename } mortgageInfo { ...HomeDetailsMortgageInfoFragment __typename } __typename } ... on HOME_BuilderCommunity { hoaFee { ...HomeDetailsHoaFeeFragment __typename } mortgageInfo { ...HomeDetailsMortgageInfoFragment __typename } __typename } __typename }""" } # 使用json参数传递数据,requests自动处理序列化和Content-Type头 response = requests.post('https://www.trulia.com/graphql', headers=headers, params=params, json=payload) print(response.status_code) print(response.json())
额外说明
- 用Python字典定义请求体比手动拼接JSON字符串更可靠,能避免引号转义、语法残留等问题。
- 若坚持使用
data参数,需确保字符串是完全合法的JSON(移除${等curl语法,所有引号正确转义),同时保持content-type: application/json头的正确设置。
内容的提问来源于stack exchange,提问作者Luka Jozić
相关产品推荐
相关产品推荐

