از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
ماژول درخواست های پایتون
سرفصلهای مطلب
معرفی
رسیدگی به درخواست های 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” را انتخاب کنید روی درست.

محتوای “سرصفحه های پاسخ” عنصر مورد نیاز ما است. میتوانید جفتهای کلید-مقدار را ببینید که اطلاعات مختلفی در مورد منبع و درخواست در اختیار دارند. بیایید سعی کنیم این مقادیر را با استفاده از 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 ثانیه است. این به درخواست شما امکان میدهد در صورت عدم اتصال به منبع، سریعتر شکست بخورد، و اگر وصل شد، زمان بیشتری برای دانلود دادهها به آن میدهد.
کوکی ها و هدرهای سفارشی
قبلا روش دسترسی به هدرها را با استفاده از 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

