Cara Melakukan Permintaan HTTP Dengan Python - Bahagian 1 Perpustakaan Standard

Cara Melakukan Permintaan HTTP Dengan Python - Bahagian 1 Perpustakaan Standard

HTTP adalah protokol yang digunakan oleh World Wide Web, sebab itu dapat berinteraksi dengannya secara programatik adalah penting: mengikis laman web, berkomunikasi dengan API perkhidmatan, atau bahkan hanya memuat turun fail, adalah semua tugas berdasarkan interaksi ini. Python menjadikan operasi sedemikian sangat mudah: Beberapa fungsi berguna telah disediakan di perpustakaan standard, dan untuk tugas yang lebih kompleks ia mungkin (dan juga disyorkan) untuk menggunakan luaran permintaan modul. Dalam artikel pertama siri ini, kami akan memberi tumpuan kepada modul terbina dalam. Kami akan menggunakan python3 dan kebanyakannya bekerja di dalam shell interaktif python: perpustakaan yang diperlukan akan diimport hanya sekali untuk mengelakkan pengulangan.

Dalam tutorial ini anda akan belajar:

  • Cara Melakukan Permintaan HTTP dengan Python3 dan Urllib.permintaan perpustakaan
  • Cara Bekerja Dengan Respons Pelayan
  • Cara memuat turun fail menggunakan urlopen atau fungsi urlretrieve


Permintaan http dengan python - pt. Saya: Perpustakaan Standard

Keperluan perisian dan konvensyen yang digunakan

Keperluan Perisian dan Konvensyen Talian Perintah Linux
Kategori Keperluan, konvensyen atau versi perisian yang digunakan
Sistem OS-bebas
Perisian Python3
Yang lain
  • Pengetahuan mengenai konsep asas pengaturcaraan berorientasikan objek dan bahasa pengaturcaraan python
  • Pengetahuan asas mengenai Protokol HTTP dan Kata Kata Kerja HTTP
Konvensyen # - Memerlukan arahan Linux yang diberikan untuk dilaksanakan dengan keistimewaan akar sama ada secara langsung sebagai pengguna root atau dengan menggunakan sudo perintah
$ - Memerlukan arahan Linux yang diberikan sebagai pengguna yang tidak layak

Melaksanakan permintaan dengan perpustakaan standard

Mari kita mulakan dengan sangat mudah Dapatkan permintaan. Kata kerja http digunakan untuk mendapatkan data dari sumber. Semasa melakukan jenis permintaan tersebut, adalah mungkin untuk menentukan beberapa parameter dalam pembolehubah bentuk: pembolehubah tersebut, dinyatakan sebagai pasangan nilai utama, Borang A rentetan pertanyaan yang "dilampirkan" ke Url sumber. Permintaan GET harus selalu ada idempotent (Ini bermakna hasil permintaan itu harus bebas dari bilangan kali ia dilakukan) dan tidak boleh digunakan untuk mengubah keadaan. Melakukan permintaan mendapatkan dengan python sangat mudah. Demi tutorial ini, kami akan memanfaatkan panggilan API NASA Terbuka yang membolehkan kami mengambil yang disebut "Gambar Hari":



>>> dari urllib.minta import urlopen >>> dengan urlopen ("https: // api.NASA.Kerajaan/Planet/APOD?api_key = demo_key ") sebagai tindak balas: ... response_content = respons.Baca () 
Salinan

Perkara pertama yang kami lakukan ialah mengimport urlopen fungsi dari urllib.permintaan Perpustakaan: Fungsi ini mengembalikan http.pelanggan.Httpresponse objek yang mempunyai beberapa kaedah yang sangat berguna. Kami menggunakan fungsi di dalam a dengan pernyataan kerana Httpresponse Objek menyokong pengurusan konteks Protokol: Sumber segera ditutup selepas pernyataan "dengan" dilaksanakan, walaupun pengecualian dibangkitkan.

The Baca kaedah yang kami gunakan dalam contoh di atas mengembalikan badan objek tindak balas sebagai bait Dan secara pilihan mengambil hujah yang mewakili jumlah bait untuk dibaca (kita akan melihat kemudian bagaimana ini penting dalam beberapa kes, terutama ketika memuat turun fail besar). Sekiranya hujah ini ditinggalkan, badan respons dibaca secara keseluruhannya.

Pada ketika ini kita mempunyai badan respons sebagai objek bait, Dirujuk oleh Response_content pembolehubah. Kita mungkin mahu mengubahnya menjadi yang lain. Untuk mengubahnya menjadi rentetan, sebagai contoh, kami menggunakan Decode kaedah, menyediakan jenis pengekodan sebagai hujah, biasanya:

>>> response_content.Decode ('UTF-8')

Dalam contoh di atas kami menggunakan UTF-8 pengekodan. Walau bagaimanapun, panggilan API yang kami gunakan dalam contoh, bagaimanapun, mengembalikan respons di Json Format, oleh itu, kami ingin memprosesnya dengan bantuan json Modul:

>>> import json json_response = json.Beban (Response_Content) 
Salinan

The json.Beban kaedah deserializes a tali, a bait atau a ByteArray contoh yang mengandungi dokumen JSON menjadi objek python. Hasil memanggil fungsi, dalam kes ini, adalah kamus:

>>> dari pprint import pprint >>> pprint (json_response) 'date': '2019-04-14', 'Penjelasan': 'Duduk dan tonton dua lubang hitam bergabung. Diilhamkan oleh '' Pengesanan langsung pertama gelombang graviti pada tahun 2015, video simulasi ini dimainkan dalam gerakan perlahan tetapi akan mengambil kira '' satu pertiga detik jika dijalankan dalam masa nyata. Ditetapkan pada tahap kosmik '' lubang hitam ditimbulkan di hadapan bintang, gas, dan '' debu. Lensa graviti mereka yang melampau cahaya dari belakang mereka '' ke dalam cincin Einstein ketika mereka lebih dekat dan akhirnya bergabung '' menjadi satu. Gelombang graviti yang tidak dapat dilihat '' yang dijana sebagai objek besar -besaran dengan cepat menyatukan imej '' yang kelihatan ke riak dan slosh di dalam dan di luar cincin '' Einstein walaupun selepas lubang hitam telah bergabung. Digelar '' GW150914, gelombang graviti yang dikesan oleh ligo adalah '' selaras dengan penggabungan 36 dan 31 solar jisim hitam '' '.3 bilion tahun cahaya. Akhir, '' Lubang Hitam Tunggal mempunyai 63 kali jisim matahari, dengan '' baki 3 jisim solar ditukar menjadi tenaga dalam '' gelombang graviti. Sejak itu, pemerhatian gelombang graviti ligo dan Virgo telah melaporkan beberapa lagi 'pengesanan sistem penggabungan besar-besaran, sementara minggu lalu' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''.',' Media_Type ':' Video ',' Service_version ':' V1 ',' Tajuk ':' Simulasi: Dua Holes Holes ',' Url ':' https: // www.Youtube.com/embed/i_88s8dwbcu?rel = 0 ' 
Salinan

Sebagai alternatif kita juga boleh menggunakan json_load fungsi (perhatikan yang hilang "s"). Fungsi ini menerima a seperti fail objek sebagai hujah: ini bermakna kita boleh menggunakannya secara langsung di Httpresponse objek:

>>> dengan urlopen ("https: // api.NASA.Kerajaan/Planet/APOD?api_key = demo_key ") sebagai tindak balas: ... json_response = json.Beban (Respons) 
Salinan

Membaca tajuk tindak balas

Kaedah lain yang sangat berguna boleh digunakan pada Httpresponse objek adalah GetHeaders. Kaedah ini mengembalikan tajuk respons sebagai pelbagai tuples. Setiap tuple mengandungi parameter header dan nilai yang sepadan:



>>> pprint (respons.GetHeaders ()) [('Server', 'OpenResty'), ('Tarikh', 'Sun, 14 Apr 2019 10:08:48 GMT'), ('jenis kandungan', 'aplikasi/json'), ( 'Kandungan panjang', '1370'), ('sambungan', 'dekat'), ('vary', 'menerima pengekodan'), ('x-ratelimit-limit', '40'), ('x -Ratelimit-Remaining ',' 37 '), (' Via ',' 1.1 Vegur, http/1.1 Api-umbrella (Apachetrafficserver [cmssf]) '), (' umur ',' 1 '), (' x-cache ',' miss '), (' akses-control-alow-origin ','*') , ('Ketat-pengangkutan-keselamatan', 'max-usia = 31536000; preload')] 

Anda dapat melihat, antara yang lain, Jenis kandungan parameter, yang, seperti yang kita katakan di atas, adalah Permohonan/JSON. Sekiranya kita mahu mengambil hanya parameter tertentu, kita boleh menggunakannya Getheader Kaedah sebaliknya, lulus nama parameter sebagai hujah:

>>> respons.GetHeader ('Kandungan-Jenis') 'Aplikasi/JSON' 
Salinan

Mendapatkan status respons

Mendapatkan kod status dan frasa sebab dikembalikan oleh pelayan selepas permintaan HTTP juga sangat mudah: yang perlu kita lakukan ialah mengakses status dan sebab sifat Httpresponse objek:

>>> respons.Status 200 >>> Respons.alasan 'ok' 
Salinan

Termasuk pembolehubah dalam permintaan GET

URL permintaan yang kami hantar di atas hanya mengandungi satu pembolehubah: API_KEY, Dan nilainya "Demo_key". Jika kita mahu lulus pelbagai pembolehubah, bukannya melampirkannya ke URL secara manual, kita dapat memberikan mereka dan nilai-nilai yang berkaitan sebagai pasangan nilai utama kamus python (atau sebagai urutan dua elemen tuples); kamus ini akan dihantar ke urllib.menghuraikan.urlencode kaedah, yang akan membina dan mengembalikan rentetan pertanyaan. Panggilan API yang kami gunakan di atas, membolehkan kami menentukan pemboleh ubah "tarikh" pilihan, untuk mengambil gambar yang berkaitan dengan hari tertentu. Inilah cara kita dapat meneruskan:

>>> dari urllib.Parse import urlencode >>> query_params =  ..."API_KEY": "Demo_Key", ..."Tarikh": "2019-04-11" >>> query_string = urlencode (query_params) >>> query_string 'api_key = demo_key & date = 2019-04-11' 
Salinan

Mula-mula kita menentukan setiap pemboleh ubah dan nilai yang sepadan sebagai pasangan nilai utama kamus, daripada yang kita lalui berkata kamus sebagai hujah kepada urlencode fungsi, yang mengembalikan rentetan pertanyaan yang diformat. Sekarang, semasa menghantar permintaan, yang perlu kita lakukan ialah melampirkannya ke URL:

>>> url = "?".Sertai (["https: // api.NASA.gov/planet/apod ", query_string])

Jika kami menghantar permintaan menggunakan URL di atas, kami mendapat respons yang berbeza dan imej yang berbeza:

'Date': '2019-04-11', 'Penjelasan': 'Apa yang kelihatan seperti lubang hitam? Untuk mengetahui, radio "teleskop dari sekitar bumi menyelaraskan pemerhatian" lubang hitam dengan ufuk acara terbesar di "langit. Sendiri, lubang hitam hanya hitam, tetapi raksasa ini "menarik diketahui dikelilingi oleh gas bercahaya. "Imej pertama dikeluarkan semalam dan menyelesaikan kawasan" di sekitar lubang hitam di pusat Galaxy M87 pada skala "di bawah yang dijangka untuk acuan acaranya. Digambarkan, "rantau tengah gelap bukanlah ufuk acara, tetapi bayangan '" Black Hole's Shadow - Rantau Pusat Gas Pemancar "" Darkened oleh Graviti Lubang Hitam Tengah. Saiz dan "'Bentuk bayangan ditentukan oleh gas cerah berhampiran" ufuk acara, dengan pesongan lensa graviti yang kuat,' "dan oleh putaran lubang hitam. Dalam menyelesaikan bayang -bayang Black Hole ini, "Teleskop Horizon Teleskop (EHT) ini menimbulkan bukti '" bahawa graviti Einstein berfungsi walaupun di kawasan yang melampau, dan "' memberikan bukti jelas bahawa M87 mempunyai lubang berputar hitam". EHT tidak dilakukan -"pemerhatian masa depan akan ditujukan ke arah yang lebih tinggi" resolusi, pengesanan kebolehubahan yang lebih baik, dan meneroka "sekitar lubang hitam di tengah -tengah" Galaxy Milky Way kami ".',' hdurl ':' https: // apod.NASA.Kerajaan/APOD/Imej/1904/M87BH_EHT_2629.jpg ',' media_type ':' imej ',' service_version ':' v1 ',' tajuk ':' imej skala cakrawala pertama dari lubang hitam ',' url ':' https: // apod.NASA.Kerajaan/APOD/Imej/1904/M87BH_EHT_960.jpg ' 


Sekiranya anda tidak perasan, url imej yang dikembalikan kepada gambar pertama yang baru dilancarkan dari lubang hitam:



Gambar yang dikembalikan oleh panggilan API - imej pertama lubang hitam

Menghantar Permintaan Pos

Menghantar permintaan pos, dengan pembolehubah 'terkandung' di dalam badan permintaan, menggunakan perpustakaan standard, memerlukan langkah tambahan. Pertama sekali, seperti yang kita lakukan sebelum ini, kita membina data pos dalam bentuk kamus:

>>> data =  ... "Variable1": "Value1", ... "Variable2": "Value2" ... 
Salinan

Setelah kami membina kamus kami, kami mahu menggunakan urlencode berfungsi seperti yang kita lakukan sebelum ini, dan juga mengekodkan rentetan yang dihasilkan ascii:

>>> post_data = urlencode (data).encode ('ascii')

Akhirnya, kami dapat menghantar permintaan kami, lulus data sebagai hujah kedua dari urlopen fungsi. Dalam kes ini kita akan menggunakan https: // httpbin.org/pos Sebagai URL destinasi (httpbin.org adalah perkhidmatan permintaan & tindak balas):

>>> dengan urlopen ("https: // httpbin.org/pos ", post_data) sebagai tindak balas: ... json_response = json.beban (respons) >>> pprint (json_response) 'args': , 'data': ", 'files': , 'form': 'variable1': 'value1', 'variable2': ' value2 ',' headers ': ' menerima-pengekodan ':' identiti ',' content-length ':' 33 ',' content-type ':' Application/x-www-form-urlencoded ',' host ' : 'httpbin.org ',' agen pengguna ':' python-urllib/3.7 ',' json ': tiada,' asal ':' xx.xx.xx.xx, xx.xx.xx.xx ',' url ':' https: // httpbin.org/pos ' 
Salinan

Permintaan itu berjaya, dan pelayan mengembalikan respons JSON yang merangkumi maklumat mengenai permintaan yang kami buat. Seperti yang anda dapat lihat pembolehubah yang kami lalui dalam badan permintaan dilaporkan sebagai nilai 'Bentuk' Kunci dalam badan tindak balas. Membaca nilai tajuk kunci, kita juga dapat melihat bahawa jenis kandungan permintaan itu Permohonan/X-www-form-urlencoded dan ejen pengguna 'Python-urllib/3.7 '.

Menghantar data JSON dalam permintaan

Bagaimana jika kita mahu menghantar perwakilan data JSON dengan permintaan kami? Mula -mula kita menentukan struktur data, daripada kita menukarnya ke JSON:

>>> orang =  ... "NameName": "Luke", ... "LastName": "Skywalker", ... "Tajuk": "Jedi Knight" ...  
Salinan

Kami juga mahu menggunakan kamus untuk menentukan tajuk tersuai. Dalam kes ini, sebagai contoh, kami ingin menyatakan bahawa kandungan permintaan kami adalah Permohonan/JSON:

>>> custom_headers =  ... "Kandungan-jenis": "Aplikasi/JSON" ... 
Salinan

Akhirnya, bukannya menghantar permintaan secara langsung, kami membuat a Permintaan objek dan kami lulus, dalam urutan: URL destinasi, data permintaan dan pengepala permintaan sebagai argumen pembina:

>>> dari urllib.permintaan permintaan import >>> req = permintaan ( ... "https: // httpbin.org/pos ", ... json.Dumps (orang).encode ('ascii'), ... custom_headers ...) 
Salinan

Satu perkara penting untuk diperhatikan ialah kami menggunakan json.membuang fungsi melepasi kamus yang mengandungi data yang kita mahu dimasukkan ke dalam permintaan sebagai hujahnya: fungsi ini digunakan untuk bersiri objek ke dalam rentetan diformat JSON, yang kami dikodkan menggunakan encode kaedah.



Pada ketika ini kita boleh menghantar kami Permintaan, lulus sebagai hujah pertama dari urlopen fungsi:

>>> dengan urlopen (req) sebagai tindak balas: ... json_response = json.Beban (Respons) 
Salinan

Mari kita periksa kandungan respons:

'args': , 'data': '"firstName": "luke", "lastname": "Skywalker", "title": "Jedi" Knight "', 'Files': , ' bentuk ': ,' headers ': ' encode encoding ':' identity ',' content-length ':' 70 ',' content-type ':' application/json ',' host ':' httpbin.org ',' agen pengguna ':' python-urllib/3.7 ',' json ': ' firstname ':' luke ',' lastname ':' Skywalker ',' tajuk ':' jedi knight ',' asal ':' xx.xx.xx.xx, xx.xx.xx.xx ',' url ':' https: // httpbin.org/pos ' 

Kali ini kita dapat melihat bahawa kamus yang dikaitkan dengan kunci "borang" dalam badan tindak balas kosong, dan yang dikaitkan dengan kunci "JSON" mewakili data yang kami hantar sebagai JSON. Seperti yang anda boleh perhatikan, walaupun parameter header tersuai yang kami hantar telah diterima dengan betul.

Menghantar permintaan dengan kata kerja HTTP selain mendapatkan atau menghantar

Semasa berinteraksi dengan API, kita mungkin perlu menggunakan Kata kerja HTTP selain daripada mendapatkan atau menghantar. Untuk melaksanakan tugas ini, kita mesti menggunakan parameter terakhir Permintaan pembina kelas dan tentukan kata kerja yang ingin kami gunakan. Kata kerja lalai adalah jika data parameter adalah Tiada, Jika tidak, siaran digunakan. Katakan kami mahu menghantar a LETAK Permintaan:

>>> req = permintaan ( ... "https: // httpbin.org/meletakkan ", ... json.Dumps (orang).encode ('ascii'), ... custom_headers, ... kaedah = 'meletakkan' ...) 
Salinan

Memuat turun fail

Satu lagi operasi yang sangat biasa yang mungkin kita mahu lakukan ialah memuat turun beberapa jenis fail dari web. Menggunakan perpustakaan standard terdapat dua cara untuk melakukannya: menggunakan urlopen fungsi, membaca respons dalam ketulan (terutamanya jika fail untuk memuat turun adalah besar) dan menulisnya ke fail tempatan "secara manual", atau menggunakan urlretrieve fungsi, yang, seperti yang dinyatakan dalam dokumentasi rasmi, dianggap sebagai sebahagian daripada antara muka lama, dan mungkin akan ditutup pada masa akan datang. Mari lihat contoh kedua -dua strategi.

Memuat turun fail menggunakan urlopen

Katakan kami ingin memuat turun tarball yang mengandungi versi terkini kod sumber kernel linux. Menggunakan kaedah pertama yang kami nyatakan di atas, kami menulis:

>>> terbaru_kernel_tarball = "https: // cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.7.tar.XZ ">>> dengan urlopen (terbaru_kernel_tarball) sebagai tindak balas: ... Dengan Terbuka ('Kernel Terkini.tar.xz ',' wb ') sebagai tarball: ... Walaupun benar: ... CHUNK = Response.Baca (16384) ... Sekiranya bahagian: ... Tarball.Tulis (bahagian) ... lain: ... rehat 
Salinan

Dalam contoh di atas kita mula -mula menggunakan kedua -dua urlopen fungsi dan buka satu di dalam dengan kenyataan dan oleh itu menggunakan protokol pengurusan konteks untuk memastikan sumber dibersihkan sebaik sahaja blok kod di mana ia digunakan dilaksanakan. Di dalam a manakala gelung, pada setiap lelaran, bahagian Rujukan pembolehubah bait bacaan dari respons, (16384 dalam kes ini - 16 kibibytes). Jika bahagian tidak kosong, kami menulis kandungan ke objek fail ("tarball"); Sekiranya kosong, ini bermakna kita menggunakan semua kandungan badan tindak balas, oleh itu kita memecahkan gelung.

Penyelesaian yang lebih ringkas melibatkan penggunaan Shutil Perpustakaan dan Copyfileobj fungsi, yang menyalin data dari objek seperti fail (dalam hal ini "Response") ke objek seperti fail lain (dalam hal ini, "Tarball"). Saiz penampan boleh ditentukan menggunakan hujah ketiga fungsi, yang, secara lalai, ditetapkan kepada 16384 bait):

>>> import shutil ... dengan urlopen (terbaru_kernel_tarball) sebagai tindak balas: ... Dengan Terbuka ('Kernel Terkini.tar.xz ',' wb ') sebagai tarball: ... Shutil.copyfileobj (respons, tarball) 
Salinan

Memuat turun fail menggunakan fungsi urlretrieve

Kaedah alternatif dan lebih ringkas untuk memuat turun fail menggunakan perpustakaan standard adalah dengan menggunakan urllib.permintaan.urlretrieve fungsi. Fungsi ini mengambil empat hujah, tetapi hanya dua kepentingan pertama kita sekarang: yang pertama adalah wajib, dan url sumber untuk dimuat turun; yang kedua adalah nama yang digunakan untuk menyimpan sumber secara tempatan. Sekiranya tidak diberikan, sumber akan disimpan sebagai fail sementara di /TMP. Kod menjadi:

>>> dari urllib.minta import urlretrieve >>> urlretrieve ("https: // cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.7.tar.xz ") ('Kernel terkini.tar.xz ', ) 
Salinan

Sangat sederhana, bukan? Fungsi ini mengembalikan tuple yang mengandungi nama yang digunakan untuk menyimpan fail (ini berguna apabila sumber disimpan sebagai fail sementara, dan namanya adalah rawak yang dihasilkan), dan Httpmessage objek yang memegang tajuk tindak balas HTTP.

Kesimpulan

Di bahagian pertama siri artikel yang didedikasikan untuk permintaan Python dan HTTP, kami melihat bagaimana untuk menghantar pelbagai jenis permintaan menggunakan hanya fungsi perpustakaan standard, dan bagaimana untuk bekerja dengan respons. Sekiranya anda ragu -ragu atau ingin meneroka perkara yang lebih mendalam, sila rujuk urllib rasmi rasmi.permintaan dokumentasi. Bahagian seterusnya siri ini akan memberi tumpuan kepada Perpustakaan Permintaan HTTP Python.

Tutorial Linux Berkaitan:

  • Pengenalan kepada Automasi, Alat dan Teknik Linux
  • Menguasai Gelung Skrip Bash
  • Gelung bersarang dalam skrip bash
  • Mint 20: Lebih baik daripada Ubuntu dan Microsoft Windows?
  • Perkara yang hendak dipasang di Ubuntu 20.04
  • Cara Bekerja Dengan API Rest WooCommerce dengan Python
  • Cara melancarkan proses luaran dengan Python dan ..
  • Mengendalikan input pengguna dalam skrip bash
  • Cara Memuat, Memunggah dan Modul Kernel Linux Senarai Hitam
  • Sistem Hung Linux? Cara melarikan diri ke baris arahan dan ..