Sending POST Requests with Custom Headers in Python Using the Requests Library

Nov 22, 2025 · Programming · 9 views · 7.8

Keywords: Python | HTTP Requests | POST Method | Custom Headers | Requests Library | JSON Serialization | Network Programming

Abstract: This technical article provides an in-depth analysis of sending POST requests with custom HTTP headers in Python. Through a practical case study, it demonstrates how to properly configure request headers and JSON payloads using the requests library, resolving common network connection errors. The article thoroughly examines HTTP protocol specifications, header field mechanisms, and differences between Python HTTP client libraries, offering complete solutions and best practice guidance for developers.

Problem Background and Error Analysis

In web development and data scraping scenarios, it is often necessary to send POST requests to servers using Python scripts. The user attempted to send a POST request with custom HTTP headers using Python's httplib module but encountered a socket.gaierror: [Errno -2] Name or service not known error. This error typically indicates DNS resolution failure or incorrect hostname configuration.

Original Code Issue Diagnosis

Analyzing the user's initial code reveals several critical issues:

First, the host variable definition includes the path component: "www.mywbsite.fr/sport/multiplex.aspx". According to HTTP protocol specifications, hostnames should not contain path information, which causes DNS resolution failure. The correct approach is to separate the hostname from the path.

Second, the params parameter is defined as a string format rather than a proper JSON object. In HTTP requests, JSON payloads need to be serialized in the correct format:

import json # Incorrect parameter format params = '"isLeftColumn":"false","liveID":"-1","userIpCountryCode":"FR","version":"null","languageCode":"fr","siteCode":"frfr","Quotation":"eu"' # Correct parameter format payload = { "isLeftColumn": False, "lID": -1, "userIpCountryCode": "FR", "version": None, "languageCode": "fr", "siteCode": "frfr", "Quotation": "eu" }

Requests Library Solution

The requests library provides more concise and powerful HTTP client functionality. Here is the complete solution:

import requests import json url = 'https://www.mywbsite.fr/Services/GetFromDataBaseVersionned' # Define request payload payload = { "isLeftColumn": False, "lID": -1, "userIpCountryCode": "FR", "version": None, "languageCode": "fr", "siteCode": "frfr", "Quotation": "eu" } # Define HTTP headers headers = { "Connection": "keep-alive", "Origin": "https://www.mywbsite.fr", "X-Requested-With": "XMLHttpRequest", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52 Safari/536.5", "Content-Type": "application/json", "Accept": "*/*", "Referer": "https://www.mywbsite.fr/data/mult.aspx", "Accept-Encoding": "gzip,deflate,sdch", "Accept-Language": "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.3", "Cookie": "ASP.NET_SessionId=j1r1b2a2v2w245; GSFV=FirstVisit=; GSRef=https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CHgQFjAA&url=https://www.mywbsite.fr/&ei=FZq_T4abNcak0QWZ0vnWCg&usg=AFQjCNHq90dwj5RiEfr1Pw; HelpRotatorCookie=HelpLayerWasSeen=0; NSC_GSPOUGS!TTM=ffffffff09f4f58455e445a4a423660; GS=Site=frfr; __utma=1.219229010.1337956889.1337956889.1337958824.2; __utmb=1.1.10.1337958824; __utmc=1; __utmz=1.1337956889.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)" } # Send POST request response = requests.post(url, data=json.dumps(payload), headers=headers) # Process response print(response.status_code) print(response.content)

Key Technical Points Analysis

URL Construction Standards: Complete URLs should include protocol, hostname, and path. In the requests library, full URLs can be used directly, and the library automatically handles hostname resolution and connection establishment.

JSON Data Serialization: When Content-Type is set to application/json, the request body must be a valid JSON string. The json.dumps() function converts Python dictionaries to JSON format strings, ensuring correct data formatting.

HTTP Header Management: HTTP headers are passed as dictionaries to the headers parameter. Note that some header fields like Content-Length are typically automatically calculated by HTTP client libraries and do not need manual specification.

Advanced Configuration and Error Handling

In practical applications, network timeouts, retry mechanisms, and exception handling should be considered:

import requests import json from requests.exceptions import RequestException def send_post_request(url, payload, headers, timeout=30): """ Enhanced version of POST request sending with error handling Args: url: Request URL payload: Request data headers: HTTP headers timeout: Timeout in seconds Returns: response: Response object or None (if error occurs) """ try: response = requests.post( url, data=json.dumps(payload), headers=headers, timeout=timeout ) response.raise_for_status() # Raise exception for non-200 status codes return response except RequestException as e: print(f"Request failed: {e}") return None # Usage example url = 'https://www.mywbsite.fr/Services/GetFromDataBaseVersionned' payload = {"isLeftColumn": False, "lID": -1} headers = {"Content-Type": "application/json"} response = send_post_request(url, payload, headers) if response: print(f"Request successful, status code: {response.status_code}") print(f"Response content: {response.text}")

Performance Optimization Recommendations

For high-frequency requests, consider using session objects to reuse TCP connections:

import requests import json # Create session object session = requests.Session() # Configure common headers session.headers.update({ "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5", "Accept": "*/*" }) # Send multiple requests url = 'https://www.mywbsite.fr/Services/GetFromDataBaseVersionned' payloads = [ {"isLeftColumn": False, "lID": -1}, {"isLeftColumn": True, "lID": 1} ] for payload in payloads: response = session.post(url, data=json.dumps(payload)) print(f"Response: {response.status_code}")

Using session objects significantly reduces connection establishment overhead and improves request efficiency.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.