مقدمه
در این مقاله با لحن آموزشی و عملی به شما نشان میدهم چطور در پروژههای اسکریپینگ با استفاده از Python Requests درخواستهای POST بسازید و مدیریت کنید. هدف این راهنما این است که پس از خواندن آن بتوانید JSON یا فرم ارسال کنید، هدرها را کنترل کنید، از نشستها (sessions) استفاده کنید و نکات مربوط به خطا، تایماوت و امنیت را پیادهسازی کنید.
آنچه خواهید آموخت:
- ارسال JSON با json parameter
- ارسال فرم با data parameter
- کنترل Content-Type و ارسال دستی JSON
- استفاده از Session برای نگهداری کوکیها و هدرها
- بهترین روشها برای خطا، retry و امنیت
ارسال JSON با requests.post
برای ارسال دادههای JSON به APIها سادهترین و امنترین راه استفاده از پارامتر json در تابع requests.post است. این روش داده را بهصورت خودکار JSON انکُد و هدر Content-Type: application/json را تنظیم میکند.
import requests
url = 'https://example.com/api'
data = {'key': 'value'}
# ارسال POST با پارامتر json
response = requests.post(url, json=data)
# خروجی: یک آبجکت Response؛ محتوای JSON را با response.json() بخوانید
print(response.json())
توضیح ورودیها و خروجیها:
- url: رشتهٔ آدرس مقصد.
- data: دیکشنری پایتون که قرار است به JSON تبدیل شود.
- تابع requests.post یک شیء Response برمیگرداند؛ متد response.json() محتوای پاسخ را به دیکشنری پایتون تبدیل میکند (در صورت معتبر بودن JSON).
خطبهخط: اول ماژول را ایمپورت میکنیم، آدرس و دیکشنری را تعریف میکنیم، سپس با پارامتری بهنام json آن را ارسال میکنیم. Requests خودش تبدیل و هدر را مدیریت میکند.
ارسال فرم (application/x-www-form-urlencoded)
برای ارسال دادههای فرم (مثلاً همان چیزی که یک فرم HTML ارسال میکند) از پارامتر data استفاده کنید؛ Requests بهصورت پیشفرض آن را فرم-انکد میکند و هدر مناسب را میگذارد.
import requests
url = 'https://example.com/api'
form_data = {'username': 'alice', 'password': 'secret'}
response = requests.post(url, data=form_data)
# خروجی معمولاً متن یا HTML است
print(response.text)
نکات:
- استفاده از data برای فایلها یا فرمهای ساده مناسب است.
- اگر بهجای فرم میخواهید JSON ارسال کنید، از json استفاده کنید تا تبدیل و هدر بهدرستی مدیریت شود.
کنترل Content-Type و ارسال دستی JSON
گاهی لازم است کنترل کامل روی Content-Type یا فرمت بدنه داشته باشید؛ مثلاً وقتی API غیرمتعارف است یا باید JSON را بهصورت رشته ارسال کنید. در این حالت از json.dumps و هدر دستی استفاده کنید.
import requests
import json
url = 'https://example.com/api'
data = {'key': 'value'}
# تبدیل دستی به JSON و تنظیم هدر
json_body = json.dumps(data)
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json_body, headers=headers)
print(response.json())
دلایل این روش:
- کنترل نسخهگذاری یا فرمتی که سرور انتظار دارد.
- در برخی موارد میخواهید کاراکترست یا هدرهای اضافی را تعیین کنید.
هشدار امنیتی: زمانی که بدنه را دستی میسازید، مطمئن شوید دادههای حساس را ایمن مدیریت میکنید (مثلاً حذف لاگهای حاوی رمز عبور).
استفاده از Sessions برای درخواستهای وضعیتدار
در اسکریپینگ معمولاً نیاز دارید چندین درخواست به یک سرور بزنید و کوکیها یا هدرها را نگه دارید. از requests.Session() استفاده کنید تا وضعیت بین درخواستها حفظ شود.
import requests
url = 'https://example.com/api'
data = {'key': 'value'}
session = requests.Session()
# هدر پیشفرض برای همه درخواستهای این جلسه
session.headers.update({'Content-Type': 'application/json'})
response = session.post(url, json=data)
print(response.json())
# session را بعد از اتمام ببندید اگر لازم است
session.close()
نکات:
- Session هدرها، کوکیها و بعضی تنظیمات را برای تمام درخواستها نگه میدارد.
- برای ورود به حساب (login)، حفظ کوکی و ادامهٔ اسکریپینگ از همان session مفید است.
مدیریت خطا، تایماوت و retry
در شبکه همیشه احتمال خطا، کندی یا قطع وجود دارد. نکات عملی زیر به پایداری اسکریپینگ کمک میکند:
- همیشه timeout مشخص کنید تا درخواستها برای مدت طولانی بلوک نشوند.
- برای خطاهای موقتی از مکانیزم retry استفاده کنید.
- محتوا و کد وضعیت HTTP را بررسی کنید و بهصورت مناسب لاگ کنید.
import requests
from requests.adapters import HTTPAdapter
from urllib3.util import Retry
url = 'https://example.com/api'
session = requests.Session()
retries = Retry(total=3, backoff_factor=0.5, status_forcelist=[429, 500, 502, 503, 504])
adapter = HTTPAdapter(max_retries=retries)
session.mount('https://', adapter)
session.mount('http://', adapter)
try:
resp = session.post(url, json={'k': 'v'}, timeout=5)
resp.raise_for_status() # اگر وضعیت خطا بود استثنا پر میکند
data = resp.json()
except requests.exceptions.Timeout:
print('Timeout occurred')
except requests.exceptions.HTTPError as e:
print('HTTP error:', e)
except requests.exceptions.RequestException as e:
print('Request failed:', e)
finally:
session.close()
توضیح:
- timeout=5: بیشینهٔ زمان منتظر ماندن برای پاسخ.
- Retry: تلاش دوباره برای خطاهای موقتی و backoff برای کاستن بار روی سرور.
- raise_for_status(): بررسی و آگاهسازی از کدهای خطای HTTP.
بهترین روشها و نکات امنیتی برای اسکریپینگ
- هرگز اطلاعات حساس (مثل توکنها یا پسوردها) را بهصورت لاگ خام ذخیره نکنید.
- از HTTPS استفاده کنید و اعتبارنامهها را در متغیرهای محیطی نگه دارید، نه در کد.
- درخواستها را با timeout و محدودیت retry کنترل کنید تا از قفلشدن جلوگیری شود.
- برای ارسال فایل از پارامتر files استفاده کنید که multipart/form-data میسازد.
- در صورت نیاز به همزمانی از ابزارهایی مانند asyncio + aiohttp یا queue + worker استفاده کنید؛ اما در ابتدا اطمینان حاصل کنید سرور را با نرخ بالا آزار ندهید.
نمونهٔ ارسال فایل (کوتاه)
# ارسال فایل بهصورت multipart/form-data
import requests
url = 'https://example.com/upload'
files = {'file': open('report.pdf', 'rb')}
response = requests.post(url, files=files)
print(response.status_code)
نکته: فایل را با حالت باینری باز کنید و پس از اتمام آن را ببندید یا از with استفاده کنید تا مدیریت منابع درست انجام شود.
جمعبندی
ارسال POST در پایتون با کتابخانهٔ Requests ساده و انعطافپذیر است: از پارامتر json برای JSON، از data برای فرمها، و از Session برای حفظ وضعیت استفاده کنید. همواره تایماوت، مدیریت خطا و محدودیت retry را در نظر بگیرید و هدرها را فقط زمانی که لازم است دستی تنظیم کنید. با رعایت این نکات، اسکریپینگ پایدارتر و امنتری خواهید داشت.





