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