Cara Melakukan Permintaan HTTP Dengan Python - Bagian 1 Perpustakaan Standar

Cara Melakukan Permintaan HTTP Dengan Python - Bagian 1 Perpustakaan Standar

HTTP adalah protokol yang digunakan oleh World Wide Web, itulah sebabnya bisa berinteraksi dengan itu secara terprogram sangat penting: Mengikis halaman web, berkomunikasi dengan API layanan, atau bahkan hanya mengunduh file, semua tugas berdasarkan interaksi ini. Python membuat operasi seperti itu sangat mudah: beberapa fungsi yang berguna sudah disediakan di perpustakaan standar, dan untuk tugas yang lebih kompleks itu mungkin (dan bahkan disarankan) untuk menggunakan eksternal permintaan modul. Dalam artikel pertama dari seri ini kami akan fokus pada modul bawaan. Kami akan menggunakan Python3 dan sebagian besar bekerja di dalam shell interaktif Python: Perpustakaan yang dibutuhkan akan diimpor hanya sekali untuk menghindari pengulangan.

Dalam tutorial ini Anda akan belajar:

  • Cara melakukan permintaan HTTP dengan Python3 dan Urllib.meminta perpustakaan
  • Bagaimana bekerja dengan respons server
  • Cara mengunduh file menggunakan fungsi urlopen atau urlretrieve


Permintaan HTTP dengan Python - PT. I: Perpustakaan Standar

Persyaratan dan konvensi perangkat lunak yang digunakan

Persyaratan Perangkat Lunak dan Konvensi Baris Perintah Linux
Kategori Persyaratan, konvensi atau versi perangkat lunak yang digunakan
Sistem OS-independen
Perangkat lunak Python3
Lainnya
  • Pengetahuan tentang konsep dasar pemrograman berorientasi objek dan bahasa pemrograman Python
  • Pengetahuan Dasar Protokol HTTP dan Kata Kerja HTTP
Konvensi # - mensyaratkan perintah linux yang diberikan untuk dieksekusi dengan hak istimewa root baik secara langsung sebagai pengguna root atau dengan menggunakan sudo memerintah
$ - mensyaratkan perintah Linux yang diberikan untuk dieksekusi sebagai pengguna biasa

Melakukan permintaan dengan perpustakaan standar

Mari kita mulai dengan sangat mudah MENDAPATKAN meminta. Get HTTP Verb digunakan untuk mengambil data dari sumber daya. Saat melakukan jenis permintaan tersebut, dimungkinkan untuk menentukan beberapa parameter dalam variabel formulir: variabel-variabel tersebut, dinyatakan sebagai pasangan nilai kunci, bentuk a string kueri yang “ditambahkan” ke Url sumber daya. Permintaan mendapatkan harus selalu idempoten (Ini berarti bahwa hasil dari permintaan harus independen dari berapa kali dilakukan) dan tidak boleh digunakan untuk mengubah keadaan. Melakukan permintaan mendapatkan python sangat mudah. Demi tutorial ini kita akan memanfaatkan panggilan API NASA terbuka yang memungkinkan kita mengambil apa yang disebut "gambar hari ini":



>>> Dari Urllib.Minta Impor Urlopen >>> Dengan Urlopen ("https: // API.NASA.GOV/Planetary/APOD?api_key = demo_key ") sebagai respons: ... response_content = respons.membaca() 
Menyalin

Hal pertama yang kami lakukan adalah mengimpor Urlopen fungsi dari Urllib.meminta Perpustakaan: Fungsi ini mengembalikan http.klien.Httpresponse objek yang memiliki beberapa metode yang sangat berguna. Kami menggunakan fungsi di dalam a dengan pernyataan karena Httpresponse objek mendukung Manajemen Konteks Protokol: Sumber daya segera ditutup setelah pernyataan "dengan" dieksekusi, bahkan jika pengecualian dibesarkan.

Itu membaca metode yang kami gunakan dalam contoh di atas mengembalikan tubuh objek respons sebagai a byte dan secara opsional mengambil argumen yang mewakili jumlah byte untuk dibaca (kita akan melihat nanti bagaimana ini penting dalam beberapa kasus, terutama saat mengunduh file besar). Jika argumen ini dihilangkan, tubuh respons dibaca secara keseluruhan.

Pada titik ini kita memiliki tubuh respons sebagai a objek bytes, direferensikan oleh response_content variabel. Kami mungkin ingin mengubahnya menjadi sesuatu yang lain. Untuk mengubahnya menjadi string, misalnya, kami menggunakan membaca sandi Metode, memberikan tipe pengkodean sebagai argumen, biasanya:

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

Dalam contoh di atas kami menggunakan UTF-8 Pengkodean. Panggilan API yang kami gunakan dalam contoh, bagaimanapun, mengembalikan respons Json Format, oleh karena itu, kami ingin memprosesnya dengan bantuan json modul:

>>> Impor JSON JSON_RESPONSE = JSON.memuat (response_content) 
Menyalin

Itu json.beban metode deserialisasi a rangkaian, A byte atau a Bytearray contoh yang berisi dokumen JSON ke dalam objek Python. Hasil memanggil fungsi, dalam hal ini, adalah kamus:

>>> Dari PPRint Impor PPRint >>> PPRint (JSON_RESPONSE) 'Date': '2019-04-14', 'Penjelasan': 'Duduk dan tonton dua lubang hitam gabungan. Terinspirasi oleh deteksi langsung pertama dari gelombang gravitasi pada tahun 2015, video simulasi '' ini diputar dalam gerakan lambat tetapi akan mengambil tentang '' sepertiga dari satu detik jika dijalankan secara real time. Diatur pada panggung kosmik 'lubang hitam diajukan di depan bintang, gas, dan' debu. Lensa gravitasi ekstrem mereka cahaya dari belakang mereka '' menjadi cincin Einstein saat mereka berputar lebih dekat dan akhirnya bergabung 'menjadi satu menjadi satu. Gelombang gravitasi yang tidak terlihat '' dihasilkan sebagai objek besar dengan cepat menyatu menyebabkan '' gambar yang terlihat menjadi riak maupun slosh baik di dalam maupun di luar cincin '' Einstein bahkan setelah lubang hitam bergabung. Dijuluki '' GW150914, gelombang gravitasi yang terdeteksi oleh Ligo '' konsisten dengan penggabungan 36 dan 31 lubang massa matahari '' pada jarak 1.3 miliar tahun cahaya. Final, '' Lubang hitam tunggal memiliki 63 kali massa matahari, dengan '' massa matahari yang tersisa dikonversi menjadi energi dalam '' gelombang gravitasi. Sejak itu Ligo dan Virgo '' Observatorium Gelombang Gravitasi telah melaporkan beberapa deteksi '' penggabungan sistem besar, sementara minggu lalu '' acara Horizon Teleskop melaporkan 'gambar horizon pertama' 'gambar dari lubang hitam'.',' media_type ':' video ',' service_version ':' v1 ',' judul ':' simulasi: dua lubang hitam gabungan ',' url ':' https: // www.Youtube.com/embed/i_88s8dwbcu?rel = 0 ' 
Menyalin

Sebagai alternatif, kami juga bisa menggunakan json_load Fungsi (perhatikan trailing yang hilang "S"). Fungsi menerima a seperti file objek sebagai argumen: ini berarti bahwa kita dapat menggunakannya langsung di Httpresponse obyek:

>>> dengan urlopen ("https: // api.NASA.GOV/Planetary/APOD?api_key = demo_key ") sebagai respons: ... JSON_RESPONSE = JSON.memuat (respons) 
Menyalin

Membaca header respons

Metode lain yang sangat berguna yang dapat digunakan pada Httpresponse objek adalah Getheaders. Metode ini mengembalikan header dari respons sebagai array tupel. Setiap tuple berisi parameter header dan nilai yang sesuai:



>>> PPRint (Respons.getHeaders ()) [('server', 'openresty'), ('date', 'sun, 14 Apr 2019 10:08:48 gmt'), ('tipe konten', 'aplikasi/json'), ( 'Konten-panjang', '1370'), ('koneksi', 'tutup'), ('vary', 'encercoding'), ('x-ratelimit-limit', '40'), ('x -Matelimit-remaining ',' 37 '), (' via ',' 1.1 Vegur, http/1.1 API-BUMBRELLA (ApachetrafficServer [cmssf]) '), (' usia ',' 1 '), (' X-Cache ',' Miss '), (' Access-Control-Allow-Origin ','*') , ('Ketat-transport-keamanan', 'Max-AGE = 31536000; preload')]] 

Anda dapat melihat, di antara yang lain, Jenis konten parameter, yang, seperti yang kami katakan di atas, adalah Aplikasi/JSON. Jika kami ingin mengambil hanya parameter tertentu, kami dapat menggunakan getheader Metode sebagai gantinya, meneruskan nama parameter sebagai argumen:

>>> Respons.getheader ('tipe konten') 'aplikasi/json' 
Menyalin

Mendapatkan status tanggapan

Mendapatkan kode status dan frasa alasan dikembalikan oleh server setelah permintaan HTTP juga sangat mudah: yang harus kami lakukan adalah mengakses status Dan alasan properti dari Httpresponse obyek:

>>> Respons.Status 200 >>> Respons.alasan 'ok' 
Menyalin

Termasuk variabel dalam permintaan GET

URL dari permintaan yang kami kirim di atas hanya berisi satu variabel: kunci API, dan nilainya "Demo_key". Jika kita ingin melewati banyak variabel, alih-alih menempelkannya ke URL secara manual, kita dapat memberikannya dan nilai-nilai yang terkait sebagai pasangan nilai kunci dari kamus Python (atau sebagai urutan dua elemen tupel); Kamus ini akan diteruskan ke Urllib.parse.Urlencode metode, yang akan membangun dan mengembalikan string kueri. Panggilan API yang kami gunakan di atas, memungkinkan kami untuk menentukan variabel "tanggal" opsional, untuk mengambil gambar yang terkait dengan hari tertentu. Inilah cara kami bisa melanjutkan:

>>> Dari Urllib.parse impor urlencode >>> query_params =  ..."API_KEY": "DEMO_KEY", ..."Tanggal": "2019-04-11" >>> query_string = urlencode (query_params) >>> query_string 'api_key = demo_key & date = 2019-04-11' 
Menyalin

Pertama-tama kami mendefinisikan setiap variabel dan nilai yang sesuai sebagai pasangan nilai kunci dari sebuah kamus, daripada yang kami lewati kamus tersebut sebagai argumen untuk Urlencode fungsi, yang mengembalikan string kueri yang diformat. Sekarang, saat mengirim permintaan, yang harus kita lakukan adalah melampirkannya ke URL:

>>> url = "?".Bergabunglah (["https: // API.NASA.GOV/Planetary/APOD ", query_string])

Jika kami mengirim permintaan menggunakan URL di atas, kami mendapatkan respons yang berbeda dan gambar yang berbeda:

'date': '2019-04-11', 'penjelasan': 'seperti apa lubang hitam itu terlihat? Untuk mengetahuinya, radio "Teleskop dari seluruh bumi pengamatan terkoordinasi" lubang hitam dengan cakrawala peristiwa terbesar yang diketahui di "langit. Sendiri, lubang hitam hanya hitam, tetapi penarik monster ini diketahui dikelilingi oleh gas bercahaya. "Gambar pertama dirilis kemarin dan menyelesaikan area" di sekitar lubang hitam di pusat Galaxy M87 pada skala "di bawah yang diharapkan untuk horizon acaranya. Foto, "Wilayah Tengah Gelap bukanlah horizon peristiwa, melainkan bayangan lubang hitam '" - wilayah tengah pemancar gas "" digelapkan oleh gravitasi lubang hitam pusat. Ukuran dan "'bentuk bayangan ditentukan oleh gas terang di dekat" horizon peristiwa, dengan defleksi lensing gravitasi yang kuat,' "dan oleh putaran lubang hitam. Dalam menyelesaikan "bayangan" lubang hitam ini, teleskop horizon peristiwa (EHT) mendukung bukti '"bahwa gravitasi Einstein bekerja bahkan di daerah ekstrem, dan"' memberikan bukti yang jelas bahwa M87 memiliki lubang hitam berputar hitam "sekitar 6 miliar massa surya surya surya 6 miliar surya 6 miliar surya pusat pemintalan pusat pusat sekitar 6 miliar surya 6 miliar surya sentral. EHT tidak dilakukan -resolusi "pengamatan di masa depan akan diarahkan untuk bahkan lebih tinggi" resolusi, pelacakan variabilitas yang lebih baik, dan mengeksplorasi "sekitar lubang hitam di tengah galaksi" Bima Sakti kami "kami.',' hdurl ':' https: // apod.NASA.GOV/APOD/IMAGE/1904/M87BH_EHT_2629.jpg ',' media_type ':' gambar ',' service_version ':' v1 ',' judul ':' gambar skala horizon pertama dari lubang hitam ',' url ':' https: // apod.NASA.GOV/APOD/IMAGE/1904/M87BH_EHT_960.jpg ' 


Jika Anda tidak memperhatikan, URL gambar yang dikembalikan menunjuk ke gambar pertama yang baru -baru ini diluncurkan dari lubang hitam:



Gambar yang dikembalikan oleh panggilan API - gambar pertama dari lubang hitam

Mengirim permintaan pos

Mengirim permintaan pos, dengan variabel 'terkandung' di dalam badan permintaan, menggunakan pustaka standar, membutuhkan langkah tambahan. Pertama -tama, seperti yang kami lakukan sebelumnya, kami membangun data postingan dalam bentuk kamus:

>>> data =  ... "Variabel1": "value1", ... "Variabel2": "value2" ... 
Menyalin

Setelah kami membangun kamus kami, kami ingin menggunakan Urlencode berfungsi seperti yang kami lakukan sebelumnya, dan juga mengkode string yang dihasilkan ASCII:

>>> post_data = urlencode (data).Encode ('ASCII')

Akhirnya, kami dapat mengirim permintaan kami, meneruskan data sebagai argumen kedua dari Urlopen fungsi. Dalam hal ini kami akan menggunakan https: // httpbin.org/posting sebagai URL tujuan (httpbin.org adalah layanan permintaan & respons):

>>> dengan urlopen ("https: // httpbin.org/post ", post_data) sebagai tanggapan: ... JSON_RESPONSE = JSON.muat (respons) >>> pPrint (json_response) 'args': , 'data': ", 'file': , 'form': 'variable1': 'value1', 'variable2': ' value2 ',' header ': ' accept-encoding ':' identity ',' konten-panjang ':' 33 ',' tipe konten ':' Aplikasi/X-WWW-Form-Urlencoded ',' Host ' : 'httpbin.org ',' agen pengguna ':' python-urllib/3.7 ',' json ': tidak ada,' asal ':' xx.xx.xx.xx, xx.xx.xx.xx ',' url ':' https: // httpbin.org/post ' 
Menyalin

Permintaan berhasil, dan server mengembalikan respons JSON yang mencakup informasi tentang permintaan yang kami buat. Seperti yang Anda lihat variabel yang kami lewati dalam tubuh permintaan dilaporkan sebagai nilai dari 'membentuk' Kunci di badan respons. Membaca nilai header kunci, kita juga dapat melihat jenis konten dari permintaan itu Aplikasi/X-WWW-Form-Urlencoded dan agen pengguna 'Python-urllib/3.7 '.

Mengirim data JSON dalam permintaan

Bagaimana jika kami ingin mengirim representasi data JSON dengan permintaan kami? Pertama kami mendefinisikan struktur data, daripada kami mengonversinya menjadi JSON:

>>> orang =  ... "FirstName": "Luke", ... "LastName": "Skywalker", ... "Judul": "Jedi Knight" ...  
Menyalin

Kami juga ingin menggunakan kamus untuk mendefinisikan header khusus. Dalam hal ini, misalnya, kami ingin menentukan bahwa konten permintaan kami adalah Aplikasi/JSON:

>>> custom_headers =  ... "Tipe konten": "Aplikasi/JSON" ... 
Menyalin

Akhirnya, alih -alih mengirim permintaan secara langsung, kami membuat a Meminta objek dan kami lulus, secara berurutan: URL tujuan, data permintaan dan header permintaan sebagai argumen konstruktornya:

>>> Dari Urllib.permintaan permintaan impor >>> req = request ( ... "https: // httpbin.org/post ", ... json.dumps (orang).Encode ('ASCII'), ... custom_headers ...) 
Menyalin

Satu hal penting yang perlu diperhatikan adalah bahwa kami menggunakan json.kesedihan fungsi melewati kamus yang berisi data yang ingin kami sertakan dalam permintaan sebagai argumennya: fungsi ini digunakan untuk Serialize objek ke dalam string yang diformat JSON, yang kami dikodekan menggunakan menyandi metode.



Pada titik ini kami dapat mengirim kami Meminta, meneruskannya sebagai argumen pertama dari Urlopen fungsi:

>>> dengan urlopen (req) sebagai tanggapan: ... JSON_RESPONSE = JSON.memuat (respons) 
Menyalin

Mari kita periksa konten tanggapannya:

'args': , 'data': '"firstName": "luke", "lastname": "skywalker", "title": "jedi" knight ",' file ': ,' bentuk ': ,' header ': ' accept-encoding ':' identity ',' konten-panjang ':' 70 ',' tipe konten ':' aplikasi/json ',' host ':' httpbin.org ',' agen pengguna ':' python-urllib/3.7 ',' json ': ' firstName ':' luke ',' lastname ':' skywalker ',' title ':' jedi knight ',' asal ':' xx.xx.xx.xx, xx.xx.xx.xx ',' url ':' https: // httpbin.org/post ' 

Kali ini kita dapat melihat bahwa kamus yang terkait dengan kunci "bentuk" di badan respons kosong, dan yang terkait dengan kunci "JSON" mewakili data yang kami kirim sebagai JSON. Seperti yang dapat Anda amati, bahkan parameter header khusus yang kami kirim telah diterima dengan benar.

Mengirim permintaan dengan kata kerja http selain mendapatkan atau memposting

Saat berinteraksi dengan API yang mungkin perlu kita gunakan Kata kerja http selain hanya mendapatkan atau memposting. Untuk menyelesaikan tugas ini, kita harus menggunakan parameter terakhir dari Meminta Konstruktor kelas dan tentukan kata kerja yang ingin kami gunakan. Kata kerja default adalah mendapatkan jika data parameter adalah Tidak ada, jika tidak, posting digunakan. Misalkan kita ingin mengirim a MELETAKKAN meminta:

>>> req = request ( ... "https: // httpbin.org/put ", ... json.dumps (orang).Encode ('ASCII'), ... custom_headers, ... metode = 'put' ...) 
Menyalin

Mengunduh file

Operasi lain yang sangat umum yang mungkin ingin kami lakukan adalah mengunduh beberapa jenis file dari web. Menggunakan pustaka standar ada dua cara untuk melakukannya: menggunakan Urlopen fungsi, membaca respons dalam potongan (terutama jika file untuk diunduh besar) dan menulisnya ke file lokal "secara manual", atau menggunakan urlretrieve fungsi, yang, sebagaimana dinyatakan dalam dokumentasi resmi, dianggap sebagai bagian dari antarmuka lama, dan mungkin menjadi sudah usang di masa depan. Mari kita lihat contoh kedua strategi.

Mengunduh file menggunakan urlopen

Katakanlah kami ingin mengunduh tarball yang berisi versi terbaru dari kode sumber kernel Linux. Menggunakan metode pertama yang kami sebutkan di atas, kami menulis:

>>> terbaru_kernel_tarball = "https: // cdn.inti.org/pub/linux/kernel/v5.X/Linux-5.0.7.ter.xz ">>> dengan urlopen (terbaru_kernel_tarball) sebagai respons: ... dengan terbuka ('Kernel terbaru.ter.xz ',' wb ') sebagai tarball: ... sementara benar: ... chunk = respons.Baca (16384) ... Jika chunk: ... Tarball.tulis (chunk) ... kalau tidak: ... merusak 
Menyalin

Dalam contoh di atas kita pertama kali menggunakan keduanya Urlopen fungsi dan membuka Satu di dalam dengan pernyataan dan karenanya menggunakan protokol manajemen konteks untuk memastikan bahwa sumber daya dibersihkan segera setelah blok kode di mana mereka digunakan dijalankan. Di dalam a ketika loop, di setiap iterasi, bingkah Referensi Variabel Byte dibaca dari respons, (16384 dalam hal ini - 16 kibibytes). Jika bingkah tidak kosong, kami menulis konten ke objek file ("Tarball"); Jika kosong, itu berarti bahwa kami mengkonsumsi semua konten dari badan respons, oleh karena itu kami memecahkan lingkaran.

Solusi yang lebih ringkas melibatkan penggunaan shutil perpustakaan dan copyFileObj fungsi, yang menyalin data dari objek seperti file (dalam hal ini "respons") ke objek seperti file lain (dalam hal ini, "Tarball"). Ukuran buffer dapat ditentukan menggunakan argumen ketiga dari fungsi, yang, secara default, diatur ke 16384 byte):

>>> impor shutil ... dengan urlopen (terbaru_kernel_tarball) sebagai respons: ... dengan terbuka ('Kernel terbaru.ter.xz ',' wb ') sebagai tarball: ... shutil.copyfileobj (respons, tarball) 
Menyalin

Mengunduh file menggunakan fungsi urlretrieve

Metode alternatif dan bahkan lebih ringkas untuk mengunduh file menggunakan pustaka standar adalah dengan menggunakan Urllib.meminta.urlretrieve fungsi. Fungsi ini membutuhkan empat argumen, tetapi hanya dua minat pertama kita sekarang: yang pertama adalah wajib, dan merupakan url sumber daya untuk diunduh; yang kedua adalah nama yang digunakan untuk menyimpan sumber daya secara lokal. Jika tidak diberikan, sumber daya akan disimpan sebagai file sementara /tmp. Kode menjadi:

>>> Dari Urllib.Minta impor urlretrieve >>> urlretrieve ("https: // cdn.inti.org/pub/linux/kernel/v5.X/Linux-5.0.7.ter.xz ") ('Kernel terbaru.ter.xz ', ) 
Menyalin

Sangat sederhana, bukan? Fungsi mengembalikan tuple yang berisi nama yang digunakan untuk menyimpan file (ini berguna ketika sumber daya disimpan sebagai file sementara, dan namanya adalah yang dihasilkan acak), dan Httpmessage objek yang memegang header respons HTTP.

Kesimpulan

Pada bagian pertama dari serangkaian artikel yang didedikasikan untuk permintaan Python dan HTTP, kami melihat cara mengirim berbagai jenis permintaan hanya menggunakan fungsi perpustakaan standar, dan cara bekerja dengan tanggapan. Jika Anda memiliki keraguan atau ingin menjelajahi hal -hal lebih mendalam, silakan berkonsultasi dengan Urllib resmi resmi.meminta dokumentasi. Bagian selanjutnya dari seri ini akan fokus pada Perpustakaan Permintaan Python HTTP.

Tutorial Linux Terkait:

  • Pengantar Otomatisasi Linux, Alat dan Teknik
  • Menguasai loop skrip bash
  • Loop bersarang dalam skrip bash
  • Mint 20: Lebih baik dari Ubuntu dan Microsoft Windows?
  • Hal -hal yang harus diinstal pada ubuntu 20.04
  • Bagaimana bekerja dengan WooCommerce Rest API dengan Python
  • Cara meluncurkan proses eksternal dengan Python dan…
  • Menangani input pengguna dalam skrip bash
  • Cara memuat, membongkar dan blacklist linux kernel modul
  • Sistem Linux Hung? Cara melarikan diri ke baris perintah dan…