ProxyTee
ExploringUpdated 2026-10-168 min readBy Alex Mercer, Lead Network Architect

Mastering Web Requests with Python: A Comprehensive Guide Using ProxyTee

In today's digital world, making HTTP requests is a fundamental skill for developers. Whether you're fetching data for web scraping, interacting with APIs, or testing web services, the ability to...

Mastering Web Requests with Python: A Comprehensive Guide Using ProxyTee

In today's digital world, making HTTP requests is a fundamental skill for developers. Whether you're fetching data for web scraping, interacting with APIs, or testing web services, the ability to programmatically send requests and handle responses is key. Python's Requests library is an incredibly popular tool for this purpose, known for its simplicity and versatility.

However, directly making requests can expose your IP address and lead to detection or blocking, especially during data-intensive tasks like web scraping. This is where ProxyTee comes into play, offering a secure and anonymous solution through its Unlimited Residential Proxies. With unlimited bandwidth and a vast pool of IPs, ProxyTee allows you to make requests without being easily detected or blocked. Let's dive into how to leverage this setup to maximize efficiency in your projects. First, let's look at an introduction to the Request Library itself:

Introduction to the Requests Library

Let's explore what Requests is, how to install it, when to use it, and what it offers.

Definition

requests is a user-friendly HTTP library for Python that provides an intuitive API for sending HTTP requests and handling responses. It’s renowned in the Python community as the go-to HTTP client with many features. The library is an essential part of many web-related projects and makes web interaction simpler. Some key features are:

  • Comprehensive API covering all HTTP methods
  • Response handling, request customization
  • Authentication, and SSL certificate management
  • Support for HTTP/1.1 out of the box

Setup

The simplest way to install Requests is using pip, the standard package manager for Python. Execute this command in your terminal:

pip install requests

To utilize the Requests library in a Python script, use the following import statement:

import requests

Use Cases

The primary use cases for the Python requests library include:

  • Making HTTP Requests: Retrieve data from web servers using GET requests.
  • Consuming APIs: Interact with web services by sending requests to API endpoints, handling their responses to access data.
  • Web Scraping: Fetch HTML documents from web pages, and use libraries like Beautiful Soup for data extraction. For optimal scraping, you'll need to avoid blocks and use proxies like ProxyTee's Residential Proxies with auto-rotation.
  • Testing Web Applications: Automate tests by simulating HTTP requests to verify the functionality of web services.
  • Downloading Files: Retrieve files like images or documents from web servers via HTTP GET requests.
man in black shirt sitting beside woman in gray shirt

HTTP Methods

Let’s explore how to work with methods like GET, POST, PUT, DELETE, and HEAD in HTTP using Python.

GET

Use the GET method to request data from a server.

import requests

response = requests.get('https://api.example.com/data')

or using requests.request():

import requests

response = requests.request('GET', 'https://api.example.com/data')

POST

Use the POST method to submit data to a server, usually for creating or updating information.

import requests

product = {
    'name': 'Limitor 500',
    'description': 'The Limitor 500 is a high-performance electronic device designed to regulate power consumption in industrial settings. It offers advanced features such as real-time monitoring, adjustable settings, and remote access for efficient energy management.',
    'price': 199.99,
    'manufacturer': 'TechCorp Inc.',
    'category': 'Electronics',
    'availability': 'In Stock'
}

response = requests.post('https://api.example.com/product', data=product)

For JSON bodies, use the json parameter:

response = requests.post('https://api.example.com/product', json=product)

You can also do it this way:

import requests

product = {
    'name': 'Limitor 500',
    'description': 'The Limitor 500 is a high-performance electronic device designed to regulate power consumption in industrial settings. It offers advanced features such as real-time monitoring, adjustable settings, and remote access for efficient energy management.',
    'price': 199.99,
    'manufacturer': 'TechCorp Inc.',
    'category': 'Electronics',
    'availability': 'In Stock'
}

response = requests.request('POST', 'https://api.example.com/product', data=product)

PUT

The PUT method updates or replaces a resource. Its structure mirrors the POST request.

PATCH

The PATCH method applies partial modifications to a resource. Like PUT, it is similar to the POST method in requests.

DELETE

The DELETE method deletes the resource specified by the URI.

import requests

response = requests.delete('https://api.example.com/products/75')

Or using requests.request() method:

import requests

response = requests.request('DELETE', 'https://api.example.com/products/75')

The HEAD method only requests the response headers, not the actual body content.

import requests

response = requests.head('https://api.example.com/resource')

Or:

import requests

response = requests.request('HEAD', 'https://api.example.com/resource')

Handling Server Responses

After sending a request, Requests provides a Response object that contains data from the server's response.

Response Object

A Response object contains the information returned by the server after a request.

import requests

response = requests.get('http://lumtest.com/myip.json')
print(response)

This might produce something like <Response [200]>.

Remember to protect against errors like invalid URLs:

try:
    response = requests.get('http://lumtest.com/myip.json')
    # handle the response
except requests.exceptions.RequestException as e:
    print('An error occurred during the request:', e)

Status Codes

HTTP status codes are used by the server to indicate if the request was successful. Access the status code from the response using the status_code attribute.

response.status_code # 200

Always check the response's status code:

import requests

response = requests.get('http://lumtest.com/myip.json')

if response.status_code == 200:
    print('Successful request!')
    # handle the response...
elif response.status_code == 404:
    print('Resource not found!')
else:
    print(f'Request failed with status code: {response.status_code}')

You can simplify the check using the response object's implicit boolean conversion:

if response:
    print('Successful request!')
    # handle the response...
else:
    print(f'Request failed with status code: {response.status_code}')

Response Headers

Headers from the server are accessible using the headers attribute:

import requests

response = requests.get('http://lumtest.com/myip.json')
response_headers = response.headers
print(response_headers)

The keys can be used in a case-insensitive way:

response_headers['content-type'] # 'application/json; charset=utf-8'

Response Content

Requests gives you multiple ways to access the content of a response:

  • response.content: returns the content as bytes
  • response.text: returns the content as string in Unicode
  • response.json(): returns the content as a dictionary after decoding it from JSON

Here's an example:

import requests

response = requests.get('http://lumtest.com/myip.json')

response_bytes = response.content
print(type(response_bytes))
print(response_bytes)
print()

response_text = response.text
print(type(response_text))
print(response_text)
print()

response_json = response.json()
print(type(response_json))
print(response_json)
print()

This can output something like this:

<class 'bytes'>
b'{"ip":"45.85.135.110","country":"US","asn":{"asnum":62240,"org_name":"Clouvider Limited"},"geo":{"city":"Ashburn","region":"VA","region_name":"Virginia","postal_code":"20149","latitude":39.0469,"longitude":-77.4903,"tz":"America/New_York","lum_city":"ashburn","lum_region":"va"}}'

<class 'str'>
{"ip":"45.85.135.110","country":"US","asn":{"asnum":62240,"org_name":"Clouvider Limited"},"geo":{"city":"Ashburn","region":"VA","region_name":"Virginia","postal_code":"20149","latitude":39.0469,"longitude":-77.4903,"tz":"America/New_York","lum_city":"ashburn","lum_region":"va"}}

<class 'dict'>
{'ip': '45.85.135.110', 'country': 'US', 'asn': {'asnum': 62240, 'org_name': 'Clouvider Limited'}, 'geo': {'city': 'Ashburn', 'region': 'VA', 'region_name': 'Virginia', 'postal_code': '20149', 'latitude': 39.0469, 'longitude': -77.4903, 'tz': 'America/New_York', 'lum_city': 'ashburn', 'lum_region': 'va'}}

Extracting from JSON object:

response_json['country'] # 'US'

Response Cookies

Access the server’s cookies with the cookies attribute:

import requests

credentials = {
    'username': 'example_user',
    'password': 'example_password'
}

response = requests.post('https://www.example.com/login', data=credentials)
cookies = response.cookies

for cookie in cookies:
    print(cookie.name, ':', cookie.value)

This could produce:

session_id : be400765483cf840dfbbd39
user_id : 7164
expires : Sat, 01 Jan 2026 14:30:00 GMT

Request Customization

Now let’s see how to configure requests with custom parameters and headers.

Query String Parameters

Pass query string parameters via the params parameter:

import requests

params = {
    'page': 1,
    'limit': 10,
    'category': 'electronics'
}

response = requests.get('https://api.example.com/products', params=params)

Alternatively, use a list of tuples:

import requests

params = [
    ('page', '1'),
    ('limit', '10'),
    ('category', 'electronics')
]

response = requests.get('https://api.example.com/products', params=params)

Or, as a bytes string:

import requests

params = b'page=1&limit=10&category=electronics'

response = requests.get('https://api.example.com/products', params=params)

Request Headers

Customize request headers with the headers option:

import requests

custom_headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
    # other headers...
}

response = requests.get('https://api.example.com/data', headers=custom_headers)

Request Cookies

You can customize cookies via the cookies parameter, as in the following example:

custom_cookies = {
    'session_id': 'be400765483cf840dfbbd39',
    'user_id': '7164'
}

response = requests.get('https://www.example.com', cookies=custom_cookies)

You can send an http.cookiejar or a dictionary.

Advanced Configurations

Explore some other advanced requests options.

Proxy Setup

Route requests through a proxy with the proxies option. This is where ProxyTee truly shines, offering rotating residential proxies that help you stay anonymous and avoid detection.

import requests

proxy = {
    'http': 'http://username:password@proxy_address:8080',
    'https': 'https://username:password@proxy_address:8080'
}

response = requests.get('https://www.example.com', proxies=proxy)

Using ProxyTee's Unlimited Residential Proxies with rotating IPs enhances your ability to make requests without facing blocks and keeps your data secure and anonymous. They are great for use cases like web scraping, bypassing geo-blocks and general privacy.

Basic Authentication

Handle HTTP basic authentication by using the auth option which uses a tuple (username, password):

import requests

username = 'sample_username'
password = 'sample_password'

response = requests.get('https://api.example.com/private/users', auth=(username, password))

SSL Certificate Verification

Disable SSL certificate verification via the verify=False parameter when needed (not recommended for production):

import requests

response = requests.get('https://api.example.com/data', verify=False)

Timeouts

Control how long requests will wait for a response with the timeout parameter (seconds). It will raise an error when time is out. Below are examples of timeout options:

import requests

response1 = requests.get("https://api.example.com/data", timeout=2)

Or specify a tuple for connection and read timeouts:

import requests

response = requests.get("https://api.example.com/data", timeout=(2.5, 4))

Handle Timeout exceptions with a try/except block:

import requests
from requests.exceptions import Timeout

try:
    response = requests.get("https://api.example.com/data", timeout=(2.5, 4))
except Timeout:
    print("The request timed out")

Conclusion

The Python requests library is a versatile tool that helps with several use cases that require web interactions and data exchange. To make these operations more secure and efficient, pairing the requests library with a reliable proxy service is key. This is where ProxyTee comes in, offering features like unlimited bandwidth, a global IP pool, and auto-rotation—all of which are essential for tasks such as web scraping and data collection.

With ProxyTee, you can access geo-restricted content, maintain anonymity, and protect your data. Additionally, ProxyTee offers great value with their affordable pricing making them ideal for businesses and individual projects requiring secure proxy services. Its user-friendly interface also makes it an excellent choice for those new to working with proxies.

ProxyTee offers a variety of proxy solutions:

ProxyTee ensures robust protection for your web interactions.

Tags:Web ScrapingPythonAPI
AM
Alex Mercer • Lead Network & Web Scraping Architect
Technically Reviewed by Marcus Vance • Director of Proxy Infrastructure & Network Security

Principal infrastructure engineer at ProxyTee specializing in rotating residential proxy networks, SOCKS5/HTTP tunneling, TLS fingerprint mitigation, and distributed data extraction pipelines.