وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

ماژول درخواست های پایتون

0 42
زمان لازم برای مطالعه: 9 دقیقه


معرفی

رسیدگی به درخواست های HTTP در هیچ زبان برنامه نویسی کار آسانی نیست. اگر در مورد پایتون صحبت کنیم، آن را با دو ماژول داخلی ارائه می کنیم، urllib و urllib2، برای رسیدگی به عملیات مربوط به HTTP. هر دو ماژول دارای مجموعه ای از عملکردهای متفاوت هستند و بارها نیاز است که با هم استفاده شوند. اشکال اصلی استفاده urllib این است که گیج کننده است (روش های کمی در هر دو موجود است urllib، urllib2)، مستندات واضح نیستند و ما باید کدهای زیادی بنویسیم تا حتی یک درخواست ساده HTTP انجام دهیم.

برای ساده‌تر کردن این موارد، یک کتابخانه شخص ثالث با کاربری آسان، معروف به درخواست ها، موجود است و بیشتر توسعه دهندگان ترجیح می دهند به جای آن از آن استفاده کنند یا urllib/urllib2. این یک کتابخانه HTTP دارای مجوز Apache2 است که توسط آن طراحی شده است urllib3 و httplib.

نصب ماژول درخواست ها

نصب این بسته، مانند سایر بسته های پایتون، بسیار ساده است. شما هم می توانید دانلود کنید کد منبع را درخواست می کند از Github و نصب یا استفاده کنید pip:

$ pip install requests

برای اطلاعات بیشتر در مورد نصب processرجوع به اسناد رسمی.

برای تأیید نصب، می توانید سعی کنید import آن را مانند زیر:

import requests

اگر هنگام وارد کردن ماژول خطایی دریافت نکردید، با موفقیت انجام شد.

ایجاد یک درخواست GET

GET تا حد زیادی پر استفاده ترین روش HTTP است. ما می توانیم از درخواست GET برای بازیابی داده ها از هر مقصدی استفاده کنیم. اجازه دهید ابتدا با یک مثال ساده شروع کنم. فرض کنید می خواهیم محتوای خانه را واکشی کنیم page از وب سایت ما و print داده های HTML حاصل را بیرون بیاورید. با استفاده از ماژول Requests می توانیم این کار را مانند زیر انجام دهیم:

import requests

r = requests.get('https://api.github.com/events')
print(r.content)

خواهد شد print پاسخ به شکل کدگذاری شده اگر می خواهید نتیجه متنی واقعی HTML را ببینید page، می توانید بخوانید .text خاصیت این شی به طور مشابه، status_code ویژگی کد وضعیت فعلی URL را چاپ می کند:

import requests

r = requests.get('https://api.github.com/events')
print(r.text)
print(r.status_code)

requests محتوای خام را رمزگشایی می کند و نتیجه را به شما نشان می دهد. اگر می خواهید بررسی کنید که چه نوع encoding استفاده می شود توسط requests، تو می توانی print با فراخوانی این مقدار را حذف کنید .encoding. حتی نوع رمزگذاری را نیز می توان با تغییر مقدار آن تغییر داد. حالا این ساده نیست؟

خواندن پاسخ

پاسخ یک درخواست HTTP می تواند حاوی هدرهای زیادی باشد که اطلاعات متفاوتی را در خود جای داده است.

httpbin یک وب سایت محبوب برای آزمایش عملکردهای مختلف HTTP است. در این مقاله استفاده خواهیم کرد httpbin/get برای تجزیه و تحلیل پاسخ به درخواست GET. اول از همه، ما باید هدر پاسخ و ظاهر آن را پیدا کنیم. شما می توانید از هر مرورگر وب مدرنی برای یافتن آن استفاده کنید، اما برای این مثال، ما از مرورگر کروم گوگل استفاده خواهیم کرد.

  • در کروم، URL را باز کنید http://httpbin.org/get، در هر نقطه راست کلیک کنید روی را pageو گزینه “Inspect” را انتخاب کنید
  • با این کار یک پنجره جدید در مرورگر شما باز می شود. را تازه کنید page و کلیک کنید روی برگه “شبکه”.
  • این برگه “شبکه” انواع مختلف درخواست های شبکه را که توسط مرورگر انجام می شود را به شما نشان می دهد. کلیک روی درخواست “get” را در ستون “Name” و برگه “Headers” را انتخاب کنید روی درست.

ابزارهای توسعه دهنده کروم با httpbin

محتوای “سرصفحه های پاسخ” عنصر مورد نیاز ما است. می‌توانید جفت‌های کلید-مقدار را ببینید که اطلاعات مختلفی در مورد منبع و درخواست در اختیار دارند. بیایید سعی کنیم این مقادیر را با استفاده از the تجزیه کنیم requests کتابخانه:

import requests

r = requests.get('http://httpbin.org/get')
print(r.headers('Access-Control-Allow-Credentials'))
print(r.headers('Access-Control-Allow-Origin'))
print(r.headers('CONNECTION'))
print(r.headers('content-length'))
print(r.headers('Content-Type'))
print(r.headers('Date'))
print(r.headers('server'))
print(r.headers('via'))

ما اطلاعات هدر را با استفاده از آن بازیابی کردیم r.headers و ما می توانیم با استفاده از کلیدهای خاص به هر مقدار هدر دسترسی داشته باشیم. توجه داشته باشید که کلید این است به حروف بزرگ و کوچک حساس نیست.

به همین ترتیب، بیایید سعی کنیم به مقدار پاسخ دسترسی پیدا کنیم. هدر بالا نشان می دهد که پاسخ در قالب JSON است: (Content-type: application/json). کتابخانه Requests دارای یک تجزیه‌کننده JSON داخلی است و ما می‌توانیم از آن استفاده کنیم requests.get('url').json() برای تجزیه آن به عنوان یک شی JSON. سپس مقدار هر کلید از نتایج پاسخ را می توان به راحتی مانند زیر تجزیه کرد:

import requests

r = requests.get('http://httpbin.org/get')

response = r.json()
print(r.json())
print(response('args'))
print(response('headers'))
print(response('headers')('Accept'))
print(response('headers')('Accept-Encoding'))
print(response('headers')('Connection'))
print(response('headers')('Host'))
print(response('headers')('User-Agent'))
print(response('origin'))
print(response('url'))

کد بالا خواهد بود print خروجی زیر:

{'headers': {'Host': 'httpbin.org', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'close', 'Accept': '*/*', 'User-Agent': 'python-requests/2.9.1'}, 'url': 'http://httpbin.org/get', 'args': {}, 'origin': '103.9.74.222'}
{}
{'Host': 'httpbin.org', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'close', 'Accept': '*/*', 'User-Agent': 'python-requests/2.9.1'}
*/*
gzip, deflate
close
httpbin.org
python-requests/2.9.1
103.9.74.222
http://httpbin.org/get

خط سوم یعنی r.json()، مقدار JSON پاسخ را چاپ کرد. ما مقدار JSON را در متغیر ذخیره کرده ایم response و سپس مقدار هر کلید را چاپ کنید. توجه داشته باشید که برخلاف مثال قبلی، کلید-مقدار به حروف کوچک و بزرگ حساس است.

پیشنهاد می‌کنیم بخوانید:  توابع درجه یک، توابع درجه بالاتر و بسته شدن در پایتون - با مثال های کد توضیح داده شده است

مشابه JSON و محتوای متنی، می توانیم استفاده کنیم requests برای خواندن محتوای پاسخ در بایت برای درخواست های غیر متنی با استفاده از .content ویژگی. این به طور خودکار رمزگشایی می شود gzip و deflate فایل های کدگذاری شده

عبور پارامترها در GET

در برخی موارد، شما باید پارامترهایی را همراه با درخواست های GET خود ارسال کنید، که به شکل رشته های پرس و جو هستند. برای انجام این کار، باید این مقادیر را در قسمت ارسال کنیم params پارامتر، مطابق شکل زیر:

import requests

payload = {'user_name': 'admin', 'password': 'password'}
r = requests.get('http://httpbin.org/get', params=payload)

print(r.url)
print(r.text)

در اینجا، ما مقادیر پارامتر خود را به payload متغیر و سپس به درخواست GET از طریق params. کد بالا خروجی زیر را برمی گرداند:

http://httpbin.org/get؟password=password&user_name=admin
{"args":{"password":"password","user_name":"admin"},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate","Connection":"close","Host":"httpbin.org","User-Agent":"python-requests/2.9.1"},"origin":"103.9.74.222","url":"http://httpbin.org/get؟password=password&user_name=admin"}

همانطور که می بینید، کتابخانه Reqeusts به طور خودکار فرهنگ لغت پارامترهای ما را به یک رشته پرس و جو تبدیل کرده و آن را به URL متصل می کند.

توجه داشته باشید که باید مراقب باشید که چه نوع داده‌هایی را از طریق درخواست‌های GET ارسال می‌کنید، زیرا payload در URL قابل مشاهده است، همانطور که در خروجی بالا مشاهده می‌کنید.

ایجاد درخواست های POST

درخواست‌های HTTP POST مخالف درخواست‌های GET هستند، زیرا برای ارسال داده‌ها به سرور در مقابل بازیابی آن‌ها در نظر گرفته شده است. اگرچه، درخواست‌های POST نیز می‌توانند داده‌ها را در پاسخ دریافت کنند، درست مانند درخواست‌های GET.

به جای استفاده از get() روش، ما نیاز به استفاده از post() روش. برای ارسال آرگومان، می‌توانیم آن را در داخل رمز عبور دهیم data پارامتر:

import requests

payload = {'user_name': 'admin', 'password': 'password'}
r = requests.post("http://httpbin.org/post", data=payload)
print(r.url)
print(r.text)

خروجی:

http://httpbin.org/post
{"args":{},"data":"","files":{},"form":{"password":"password","user_name":"admin"},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate","Connection":"close","Content-Length":"33","Content-Type":"application/x-www-form-urlencoded","Host":"httpbin.org","User-Agent":"python-requests/2.9.1"},"json":null,"origin":"103.9.74.222","url":"http://httpbin.org/post"}

داده ها به طور پیش فرض “فرم کدگذاری” خواهند شد. همچنین می‌توانید درخواست‌های هدر پیچیده‌تری مانند یک تاپل را ارسال کنید، اگر چندین مقدار دارای کلید یکسان، یک رشته به جای فرهنگ لغت یا یک فایل رمزگذاری شده چند قسمتی باشند.

ارسال فایل با POST

گاهی لازم است یک یا چند فایل را به طور همزمان به سرور ارسال کنیم. به عنوان مثال، اگر کاربری در حال ارسال فرمی باشد و فرم شامل فیلدهای فرم مختلف برای آپلود فایل‌ها باشد، مانند تصویر نمایه کاربر، رزومه کاربر و غیره. درخواست‌ها می‌توانند چندین فایل را مدیریت کنند. روی یک درخواست واحد این را می توان با قرار دادن فایل ها در لیستی از تاپل ها، مانند زیر به دست آورد:

import requests

url = 'http://httpbin.org/post'
file_list = (
    ('image', ('image1.jpg', open('image1.jpg', 'rb'), 'image/png')),
    ('image', ('image2.jpg', open('image2.jpg', 'rb'), 'image/png'))
)

r = requests.post(url, files=file_list)
print(r.text)

تاپل های حاوی اطلاعات فایل ها در فرم هستند (field_name, file_info).

سایر انواع درخواست HTTP

مشابه GET و POST، می‌توانیم سایر درخواست‌های HTTP مانند PUT، DELETE، HEAD و OPTIONS را با استفاده از requests کتابخانه، مانند زیر:

import requests

requests.put('url', data={'key': 'value'})
requests.delete('url')
requests.head('url')
requests.options('url')

مدیریت تغییر مسیرها

تغییر مسیر در HTTP به معنای ارسال درخواست شبکه به یک URL دیگر است. به عنوان مثال، اگر ما درخواستی برای “http://www.github.com“، به ” هدایت می شودhttps://github.com“با استفاده از a 301 تغییر مسیر.

import requests

r = requests.post("http://www.github.com")
print(r.url)
print(r.history)
print(r.status_code)

خروجی:

https://github.com/
(<Response (301)>, <Response (301)>)
200

همانطور که می بینید تغییر مسیر process به طور خودکار توسط requests، بنابراین نیازی نیست خودتان با آن مقابله کنید. این history ویژگی شامل لیستی از تمام اشیاء پاسخ ایجاد شده برای تکمیل تغییر مسیر است. در مثال ما، دو Response اشیاء با کد پاسخ 301 ایجاد شدند. پاسخ های HTTP 301 و 302 به ترتیب برای تغییر مسیر دائم و موقت استفاده می شوند.

اگر نمی‌خواهید کتابخانه درخواست‌ها به‌طور خودکار از تغییر مسیرها پیروی کند، می‌توانید آن را با عبور از مسیر غیرفعال کنید. allow_redirects=False پارامتر به همراه درخواست

رسیدگی به وقفه های زمانی

یکی دیگر از پیکربندی‌های مهم این است که به کتابخانه ما می‌گوید چگونه با وقفه‌های زمانی یا درخواست‌هایی که برگشت آنها خیلی طول می‌کشد، رسیدگی کند. ما می توانیم پیکربندی کنیم requests برای توقف انتظار برای درخواست های شبکه با استفاده از timeout پارامتر. به صورت پیش فرض، requests تایم اوت نخواهد شد بنابراین، اگر ما این ویژگی را پیکربندی نکنیم، برنامه ما ممکن است به طور نامحدود متوقف شود، که عملکرد مورد نظر شما نیست. process که کاربر را منتظر نگه می دارد.

import requests

requests.get('http://www.google.com', timeout=1)

در اینجا، اگر سرور در عرض 1 ثانیه پاسخ ندهد (که هنوز برای یک برنامه دنیای واقعی تهاجمی است) یک استثنا ایجاد می شود. برای اینکه این مورد بیشتر از کار بیفتد (به عنوان مثال)، باید محدودیت زمانی را روی مقدار بسیار کمتری مانند 0.001 تنظیم کنید.

مهلت زمانی را می توان برای هر دو عملیات “connect” و “read” درخواست با استفاده از یک tuple پیکربندی کرد، که به شما امکان می دهد هر دو مقدار را به طور جداگانه مشخص کنید:

import requests

requests.get('http://www.google.com', timeout=(5, 14))

در اینجا، تایم اوت “اتصال” 5 ثانیه و تایم اوت “خواندن” 14 ثانیه است. این به درخواست شما امکان می‌دهد در صورت عدم اتصال به منبع، سریع‌تر شکست بخورد، و اگر وصل شد، زمان بیشتری برای دانلود داده‌ها به آن می‌دهد.

پیشنهاد می‌کنیم بخوانید:  ابزارهای تکرار پایتون: filter()، islice()، map() و zip()

کوکی ها و هدرهای سفارشی

قبلا روش دسترسی به هدرها را با استفاده از headers ویژگی. به طور مشابه، ما می‌توانیم با استفاده از یک پاسخ به کوکی‌ها دسترسی پیدا کنیم cookies ویژگی.

به عنوان مثال، مثال زیر روش دسترسی به یک کوکی با نام را نشان می دهد cookie_name:

import requests

r = requests.get('http://www.examplesite.com')
r.cookies('cookie_name')

ما همچنین می‌توانیم با ارائه یک فرهنگ لغت به سرور، کوکی‌های سفارشی را به سرور ارسال کنیم cookies پارامتر در درخواست GET ما.

import requests

custom_cookie = {'cookie_name': 'cookie_value'}
r = requests.get('http://www.examplesite.com/cookies', cookies=custom_cookie)

کوکی ها همچنین می توانند در یک منتقل شوند ظرف کلوچه هدف – شی. این به شما امکان می دهد کوکی ها را برای یک مسیر متفاوت ارائه دهید.

import requests

jar = requests.cookies.RequestsCookieJar()
jar.set('cookie_one', 'one', domain='httpbin.org', path='/cookies')
jar.set('cookie_two', 'two', domain='httpbin.org', path='/other')

r = requests.get('https://httpbin.org/cookies', cookies=jar)
print(r.text)

خروجی:

{"cookies":{"cookie_one":"one"}}

به طور مشابه، ما می‌توانیم با اختصاص یک دیکشنری به سربرگ درخواست با استفاده از هدرهای سفارشی ایجاد کنیم headers پارامتر.

import requests

custom_header = {'user-agent': 'customUserAgent'}

r = requests.get('https://samplesite.org', headers=custom_header)

شی جلسه

شی جلسه عمدتاً برای حفظ پارامترهای خاص مانند کوکی ها در درخواست های مختلف HTTP استفاده می شود. یک شی جلسه ممکن است از یک اتصال TCP برای رسیدگی به چندین درخواست و پاسخ شبکه استفاده کند که منجر به بهبود عملکرد می شود.

import requests

first_session = requests.Session()
second_session = requests.Session()

first_session.get('http://httpbin.org/cookies/set/cookieone/111')
r = first_session.get('http://httpbin.org/cookies')
print(r.text)

second_session.get('http://httpbin.org/cookies/set/cookietwo/222')
r = second_session.get('http://httpbin.org/cookies')
print(r.text)

r = first_session.get('http://httpbin.org/anything')
print(r.text)

خروجی:

{"cookies":{"cookieone":"111"}}

{"cookies":{"cookietwo":"222"}}

{"args":{},"data":"","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate","Connection":"close","Cookie":"cookieone=111","Host":"httpbin.org","User-Agent":"python-requests/2.9.1"},"json":null,"method":"GET","origin":"103.9.74.222","url":"http://httpbin.org/anything"}

مسیر httpbin /cookies/set/{name}/{value} یک کوکی با name و value. در اینجا، ما مقادیر مختلف کوکی را برای هر دو تنظیم می کنیم first_session و second_session اشیاء. می توانید ببینید که همان کوکی در تمام درخواست های شبکه آینده برای یک جلسه خاص بازگردانده می شود.

به طور مشابه، می‌توانیم از شی session برای حفظ پارامترهای خاص برای همه درخواست‌ها استفاده کنیم.

import requests

first_session = requests.Session()

first_session.cookies.update({'default_cookie': 'default'})

r = first_session.get('http://httpbin.org/cookies', cookies={'first-cookie': '111'})
print(r.text)

r = first_session.get('http://httpbin.org/cookies')
print(r.text)

خروجی:

{"cookies":{"default_cookie":"default","first-cookie":"111"}}

{"cookies":{"default_cookie":"default"}}

همانطور که می بینید، default_cookie با هر درخواست جلسه ارسال می شود. اگر هر پارامتر اضافی را به آن اضافه کنیم cookie شی، آن را به default_cookie. "first-cookie": "111" به کوکی پیش فرض اضافه می شود "default_cookie": "default"

استفاده از پروکسی ها

این proxies آرگومان برای پیکربندی یک سرور پراکسی برای استفاده در درخواست های شما استفاده می شود.

http = "http://10.10.1.10:1080"
https = "https://10.10.1.11:3128"
ftp = "ftp://10.10.1.10:8080"

proxy_dict = {
  "http": http,
  "https": https,
  "ftp": ftp
}

r = requests.get('http://sampleurl.com', proxies=proxy_dict)

این requests کتابخانه نیز پشتیبانی می کند جوراب پروکسی ها این یک ویژگی اختیاری است و به آن نیاز دارد requests(socks) وابستگی قبل از استفاده نصب شود. مانند قبل، می توانید آن را با استفاده از آن نصب کنید pip:

$ pip install requests(socks)

پس از نصب، می توانید از آن مانند شکل زیر استفاده کنید:

proxies = {
  'http': 'socks5:user:pass@host:port'
  'https': 'socks5:user:pass@host:port'
}

SSL Handling

همچنین می‌توانیم از کتابخانه Requests برای تأیید گواهی HTTPS یک وب‌سایت با عبور استفاده کنیم verify=true با درخواست

import requests

r = requests.get('https://www.github.com', verify=True)

در صورت وجود هر گونه مشکل در SSL سایت، با خطا مواجه می شود. اگر نمی خواهید صحت داشته باشید، فقط پاس کنید False بجای True. این پارامتر روی تنظیم شده است True به صورت پیش فرض.

دانلود یک فایل

برای دانلود فایل با استفاده از requests، می‌توانیم آن را با استریم مطالب یا دانلود مستقیم کل آن دانلود کنیم. این stream flag برای نشان دادن هر دو رفتار استفاده می شود.

همانطور که احتمالا حدس زده اید، اگر stream است True، سپس requests محتوا را پخش خواهد کرد. اگر stream است False، تمام محتوا در حافظه بارگیری می شود و آن را به شما باز می گرداند.

برای استریم محتوا، می‌توانیم تکه تکه محتوا را با استفاده از آن تکرار کنیم iter_content روش یا تکرار خط به خط با استفاده از iter_line. در هر صورت فایل را قسمت به قسمت دانلود می کند.

مثلا:

import requests

r = requests.get('https://cdn.pixabay.com/photo/2018/07/05/02/50/sun-hat-3517443_1280.jpg', stream=True)
downloaded_file = open("sun-hat.jpg", "wb")
for chunk in r.iter_content(chunk_size=256):
    if chunk:
        downloaded_file.write(chunk)

کد بالا یک تصویر را از آن دانلود می کند پیکسابای سرور و ذخیره آن در یک فایل محلی، sun-hat.jpg.

ما همچنین می توانیم داده های خام را با استفاده از raw اموال و stream=True در درخواست

import requests

r = requests.get("http://exampleurl.com", stream=True)
r.raw

برای دانلود یا پخش محتوا، iter_content() راه ارجح است

خطاها و استثنائات

requests در صورت بروز مشکل در شبکه، انواع مختلفی از استثناها و خطاها را ایجاد می کند. همه استثناها به ارث رسیده اند requests.exceptions.RequestException کلاس

در اینجا شرح کوتاهی از خطاهای رایجی که ممکن است با آنها برخورد کنید آورده شده است:

  • ConnectionError استثنا در صورت پرتاب می شود DNS failure،refused connection یا هر مشکل مرتبط با اتصال دیگر
  • Timeout در صورت اتمام زمان درخواست مطرح می شود.
  • TooManyRedirects اگر درخواستی از حداکثر تعداد تغییر مسیرهای از پیش تعریف شده بیشتر شود، مطرح می شود.
  • HTTPError استثنا برای پاسخ های HTTP نامعتبر مطرح می شود.

برای فهرست کامل‌تر و شرح استثناهایی که ممکن است در آن‌ها اجرا کنید، این را بررسی کنید مستندات.

نتیجه

در این آموزش برای شما بسیاری از ویژگی های آن را توضیح دادم requests کتابخانه و روش های مختلف استفاده از آن شما می توانید استفاده کنید requests کتابخانه نه تنها برای تعامل با REST API، بلکه می تواند به همان اندازه برای جمع کردن داده ها از یک وب سایت یا برای دانلود فایل ها از وب استفاده شود.

نمونه های بالا را اصلاح کنید و امتحان کنید و در صورت داشتن هر گونه سوال در زیر نظر دهید requests.

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-27 17:19:06

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید