Menguak Rahasia Otomatisasi Python: Jurus Jitu Bikin Bot Cerdas dan Web Scraper Sakti

ikramlink April 25, 2026
Menguak Rahasia Otomatisasi Python: Jurus Jitu Bikin Bot Cerdas dan Web Scraper Sakti

Pernah nggak sih kamu merasa hari-harimu di depan laptop kok gitu-gitu aja? Setiap pagi buka tab yang sama, klik tombol yang sama, atau copy-paste data dari satu website ke Excel? Saya pernah. Dulu, saya sampai ngalamin tangan pegal kayak habis ikut kontes 'siapa paling cepat ngeklik'. Saking frustrasinya, saya sampai mikir, "Masa sih di zaman serba digital ini nggak ada cara yang lebih santai?" Nah, di titik itulah saya berkenalan dengan Python dan jurus otomatisasinya. Rasanya kayak nemu koki pribadi yang siap masak makanan favoritmu setiap hari tanpa kamu perlu repot belanja atau nyuci piring. Hidup langsung berasa lebih ringan! Dan hari ini, saya mau ajak kamu buat jadi koki otomatisasi itu juga.

Dunia programmer itu bukan cuma tentang bikin aplikasi canggih, tapi juga tentang bagaimana kita bisa membuat hidup kita (dan orang lain) jadi lebih efisien. Salah satu senjata paling ampuh untuk mewujudkan itu adalah otomatisasi dengan Python. Bayangkan kamu punya asisten super cerdas yang siap melakukan tugas-tugas repetitif di internet, mulai dari mengumpulkan informasi sampai berinteraksi dengan sebuah situs web. Inilah yang akan kita bahas tuntas hari ini: bagaimana membuat script otomatisasi Python untuk bot dan web scraping.

Memahami Pilar Otomatisasi: Web Scraping dan Bot

Sebelum kita terjun ke 'dapur' koding, mari kita pahami dulu dua pilar utama otomatisasi yang sering disebut-sebut:

1. Web Scraping: Sang Detektif Pengumpul Informasi

Analoginya begini: bayangkan kamu disuruh mencari semua resep kue bolu pandan yang ada di satu tumpukan majalah resep super banyak. Kalau kamu kerjakan manual, kamu harus buka satu per satu majalah, baca isinya, cari resepnya, lalu salin. Capek, kan?

Nah, web scraping itu ibarat kamu punya detektif super cepat dan teliti yang bisa membaca semua majalah itu dalam hitungan detik, menemukan semua resep bolu pandan, dan menyajikannya dalam format rapi yang kamu minta. Dalam konteks dunia maya, detektif ini adalah script Python kita yang 'mengunjungi' website, membaca kode HTML-nya, lalu mengekstrak data spesifik yang kita inginkan (misalnya harga produk, berita terbaru, atau data kontak). Ini adalah cara paling efisien untuk mengumpulkan data dari website secara massal.

Untuk tugas ini, Python punya dua 'alat' andalan yang paling sering dipakai:

  • Requests: Ini adalah kurir kita yang bertugas pergi ke server website, mengambil semua "paket" berupa kode HTML, dan membawanya pulang ke script kita.
  • BeautifulSoup (bs4): Setelah kurir membawa pulang "paket" HTML, BeautifulSoup adalah 'tukang sortir' kita yang super pintar. Dia akan membongkar "paket" itu, memahami struktur isinya (layaknya membaca daftar isi sebuah buku), dan membantu kita menemukan bagian spesifik yang kita inginkan (misalnya judul artikel, harga, atau paragraf tertentu).

2. Bot Automation: Sang Supir Robot yang Patuh

Kalau web scraping itu kayak detektif yang hanya mengamati dan mencatat, nah bot automation ini lebih mirip supir robot yang bisa kamu program untuk melakukan berbagai tindakan. Bayangkan kamu punya mobil mainan robot yang bisa kamu atur untuk menyalakan mesin, injak gas, belok kanan, belok kiri, bahkan mengisi formulir parkir otomatis. Semua tanpa kamu sentuh!

Dalam dunia web, bot automation artinya kita membuat script Python yang bisa berinteraksi langsung dengan browser web atau aplikasi lain. Dia bisa membuka browser, mengetikkan sesuatu di kolom pencarian, mengklik tombol, mengisi formulir login, atau bahkan mengunggah file. Ini sangat berguna untuk tugas-tugas yang membutuhkan interaksi, bukan hanya pengambilan data pasif.

Untuk bot automation, Selenium adalah 'supir' utama kita. Selenium adalah tool canggih yang memungkinkan kita mengendalikan browser sungguhan (seperti Chrome atau Firefox) langsung dari script Python kita. Kamu bisa memerintahkannya untuk 'melihat' elemen di halaman, 'mengklik' mereka, 'mengetikkan' teks, dan banyak lagi.

Merakit Senjata Otomatisasi Python-mu: Persiapan dan Contoh Sederhana

Oke, kita sudah tahu "bahan-bahannya". Sekarang saatnya "merakit" atau "memasak" script kita. Pertama-tama, pastikan kamu sudah punya Python terinstal di komputermu. Kalau belum, langsung unduh di sini. Setelah itu, kita perlu menginstal beberapa "alat dapur" tambahan:


pip install requests beautifulsoup4 selenium webdriver-manager

Penjelasan Singkat:

  • requests: Untuk mengambil halaman web.
  • beautifulsoup4: Untuk mengurai (parse) HTML.
  • selenium: Untuk mengendalikan browser.
  • webdriver-manager: Ini penting! Selenium butuh driver browser (misalnya ChromeDriver untuk Chrome). webdriver-manager akan mengunduh dan mengelola driver ini secara otomatis, jadi kamu tidak perlu repot mengunduhnya manual dan menyesuaikan versinya. Ini penyelamat hidup banget!

Contoh 1: Web Scraping Sederhana (Mengambil Judul Halaman)

Mari kita coba mengambil judul dari sebuah website sederhana. Anggaplah kita ingin tahu judul artikel pertama di blog saya (fiktif).


import requests
from bs4 import BeautifulSoup
# URL target kita, ibarat alamat perpustakaan yang mau kita kunjungi
url = 'http://quotes.toscrape.com/' # Contoh situs web scraping, bukan blog saya beneran ya :)
try:
# Minta kurir (requests) untuk pergi ke URL itu dan ambil paket HTML-nya
response = requests.get(url)
response.raise_for_status() # Cek apakah ada error saat mengambil halaman
# Jika berhasil, berikan paket HTML ke tukang sortir (BeautifulSoup)
soup = BeautifulSoup(response.text, 'html.parser')
# Sekarang, suruh tukang sortir mencari elemen dengan tag 
title_element = soup.find('title')
if title_element:
print(f"Judul Halaman: {title_element.get_text()}")
else:
print("Judul halaman tidak ditemukan.")
except requests.exceptions.RequestException as e:
print(f"Ada masalah saat koneksi: {e}")
except Exception as e:
print(f"Terjadi error: {e}")
</code></pre>
<p>Ketika kamu menjalankan kode di atas, script Pythonmu akan "mengunjungi" <code>http://quotes.toscrape.com/</code>, mengambil seluruh kode HTML-nya, lalu mencari tag <code><title></code>, dan mencetak teks di dalamnya. Simpel, bukan?</p>
<h3>Contoh 2: Bot Automation Sederhana (Membuka Browser dan Menuju Halaman)</h3>
<p>Sekarang mari kita coba menyuruh 'supir robot' kita untuk membuka browser dan pergi ke Google.</p>
<pre><code>
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import time
# Inisialisasi service driver Chrome secara otomatis
# Ini seperti menyuruh supir robot kita untuk siap-siap menyalakan mobil Chrome
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
# Perintahkan supir robot untuk membuka browser dan pergi ke Google
print("Membuka browser dan menuju Google...")
driver.get("https://www.google.com")
# Kasih jeda sebentar biar kita bisa lihat hasilnya (ibarat supir robot menunggu instruksi)
time.sleep(5)
print("Berhasil membuka Google!")
except Exception as e:
print(f"Terjadi error saat menjalankan bot: {e}")
finally:
# Penting: Setelah selesai, pastikan supir robot kita mematikan mesinnya (menutup browser)
print("Menutup browser...")
driver.quit()
</code></pre>
<p>Jalankan script ini, dan kamu akan melihat browser Chrome otomatis terbuka, menuju ke halaman Google, lalu setelah beberapa detik, browser itu akan tertutup sendiri. Keren, kan? Dari sini, kamu bisa mengembangkan lebih lanjut untuk mengisi form, mengklik tombol, dan banyak lagi!</p>
<h2>Tips dan Trik ala Programmer Profesional (Anti-Blokir dan Anti-Pusing)</h2>
<p>Membuat script otomatisasi itu seperti merakit mesin. Ada etika dan panduannya agar mesinmu awet dan tidak merugikan orang lain:</p>
<ul>
<li><strong>Hormati Website (Baca <code>robots.txt</code>):</strong> Ibarat masuk rumah orang, kita harus tahu aturan mainnya. Sebelum scraping, selalu cek <code>/robots.txt</code> di website target (contoh: <code>https://www.namasitus.com/robots.txt</code>). File ini akan memberitahu kamu bagian mana dari situs yang boleh di-scrape dan bagian mana yang tidak.</li>
<li><strong>Jangan Ngebut (Gunakan <code>time.sleep()</code>):</strong> Kalau kamu mengirim terlalu banyak permintaan ke server dalam waktu singkat, server bisa menganggapmu sebagai serangan dan memblokir IP-mu. Selalu beri jeda (misalnya <code>time.sleep(2)</code> untuk jeda 2 detik) antara setiap permintaan. Anggaplah ini sebagai sopan santun digital.</li>
<li><strong>Tangani Error dengan Bijak (<code>try-except</code>):</strong> Di dunia coding, error itu teman. Selalu gunakan blok <code>try-except</code> untuk mengantisipasi masalah (misalnya koneksi internet putus, elemen tidak ditemukan). Ini seperti memasang sabuk pengaman di mobil.</li>
<li><strong>Selalu Tutup Driver (<code>driver.quit()</code>):</strong> Kalau pakai Selenium, setelah selesai beraksi, selalu panggil <code>driver.quit()</code> untuk menutup browser dan membersihkan resource. Kalau tidak, bisa-bisa kamu punya banyak browser "hantu" yang berjalan di latar belakang.</li>
<li><strong>Virtual Environment adalah Sahabatmu:</strong> Saat menginstal banyak library, kadang bisa tabrakan versinya. Gunakan <a href="https://docs.python.org/3/library/venv.html" target="_blank">virtual environment</a> untuk mengisolasi project-mu. Ini seperti punya kotak perkakas khusus untuk setiap proyek agar tidak campur aduk.</li>
</ul>
<h2>Penutup: Saatnya Kamu Jadi Sutradara Otomatisasi!</h2>
<p>Melihat betapa mudahnya Python bisa membuat hidup kita lebih santai, rasanya seperti menemukan harta karun, bukan? Dari sekadar mengambil data pasif dengan web scraping, hingga mengendalikan browser secara aktif dengan bot automation, Python memberikan kekuatan tak terbatas di tanganmu.</p>
<p>Ingat, ini hanyalah permulaan. Sama seperti belajar memasak, ada banyak resep dan teknik yang bisa kamu eksplorasi. Kunci utamanya adalah berani mencoba, bereksperimen, dan jangan takut salah. Setiap error adalah pelajaran baru. Jadi, tunggu apa lagi? Ambil laptopmu, buka editor kode favoritmu, dan mulailah "memasak" script otomatisasi pertamamu! Selamat menjelajah dunia otomatisasi dengan Python!</p>
</div>
<div class='mt-8 pt-4 border-t border-gray-200 dark:border-dark-border flex flex-wrap gap-2'>
<a class='px-2.5 py-1 bg-gray-50 dark:bg-dark-700 border border-gray-200 dark:border-dark-border text-blue-600 dark:text-dark-link text-xs font-medium rounded-full hover:bg-gray-100 dark:hover:bg-dark-border transition-colors' href='https://script.pintarapp.com/search/label/Bot'>Bot</a>
<a class='px-2.5 py-1 bg-gray-50 dark:bg-dark-700 border border-gray-200 dark:border-dark-border text-blue-600 dark:text-dark-link text-xs font-medium rounded-full hover:bg-gray-100 dark:hover:bg-dark-border transition-colors' href='https://script.pintarapp.com/search/label/Python'>Python</a>
<a class='px-2.5 py-1 bg-gray-50 dark:bg-dark-700 border border-gray-200 dark:border-dark-border text-blue-600 dark:text-dark-link text-xs font-medium rounded-full hover:bg-gray-100 dark:hover:bg-dark-border transition-colors' href='https://script.pintarapp.com/search/label/Web%20Scraping'>Web Scraping</a>
</div>
<div class='mt-8 pt-4 border-t border-gray-200 dark:border-dark-border flex justify-center w-full'>
<script async='async' data-cfasync='false' src='https://pl28962147.profitablecpmratenetwork.com/7797da862e5153c59970a9d83ab07d97/invoke.js'></script>
<div id='container-7797da862e5153c59970a9d83ab07d97'></div>
</div>
</div>
</div></div>
</main>
<!-- KOLOM 3: SIDEBAR KANAN (Tetap 3 Kolom / 25%) -->
<aside class='lg:col-span-3 w-full order-3 sticky top-20'>
<!-- Slot Iklan Atas Sidebar Kanan -->
<div class='w-full mb-4 flex justify-center items-center overflow-hidden adsterra-slot' data-h='250' data-key='017ff5a2024d32a8d605ed757a4d6002' data-w='300'>
<div class='no-items section' id='ad-sidebar-right'></div>
</div>
<div class='sidebar-right section' id='sidebar-right'><div class='widget PopularPosts' data-version='2' id='PopularPosts1'>
<div class='widget bg-white dark:bg-dark-800 border border-gray-200 dark:border-dark-border p-4 rounded-md shadow-sm'>
<h2>Trending</h2>
<div class='space-y-3'>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/dari-nol-jadi-pro-bangun-dapps-smart.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_uYMqfvt0wTrZ_KUwaN7ipzgj2sy1RQxMydNBZabB6fk1F02KWKgRtir3KSG7v8ukz7JqkqKoV2SpEhF0aikxvKUJlO1XPuiEHvL5o'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Dari Nol Jadi Pro: Bangun dApps & Smart Contract di Solana yang Ngebut Abis!</h4>
</div>
</a>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/otomatisasi-kompresi-gambar-massal-ke.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYDgcW77dIwQ7Fn8qRlFuAhiTxJ0mIpi2gvJ1ZAZhhjppBXp9F0yF6zzOIyOJqoiyWqubxaQhI6HJwoeyhsG8XDBRZhpsZ7NBTltmGv8sibMyKJgGnj9l7fkrTlqSHueUoNOcU7NLJOQbdx5vJPj4_DHrWxmlVtsdjaKsT0pC63WM8UJtLtJQpFtprsls/s400/compress%20massal%20webp.jpg'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Otomatisasi Kompresi Gambar Massal ke format WebP</h4>
</div>
</a>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/rahasia-bikin-hidup-lebih-mudah-python.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_tZSYSD_cHRpfo7UpsHHqvS5LBmb_ompfarKWMstMjX7LKMbVvFZdaj45JuAru7nr68CaCQFRo9NvyxhfGSvjCZji1oIKslYBvKgz4'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Rahasia Bikin Hidup Lebih Mudah: Python untuk Bot & Web Scraping Otomatis!</h4>
</div>
</a>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/python-jadi-kuncian-bikin-bot-otomasi.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_tp0FmvAeBQ7q2UUJ7XlJBnP310SI4yqLz0sgkbbjWPSZ6l-JJlPiuUepCDLcpc9zVA9a59ahi9qgOkd5q3q-zU1Y05PFX_zeNRm6Ngz3a1NBSUGtH9'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Python Jadi Kuncian! Bikin Bot Otomasi & Web Scraping Anti Ribet (Panduan Lengkap)</h4>
</div>
</a>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/dari-nol-sampai-pro-bikin-kalkulator.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_tug2PafYUA_OKgdEfjpEh_8T4xj8QB0qAmoiboQmZOBhlgesLnbYoaudNAm7Nz_zuuDMgZZJWQJGOjhLNY5ipxyrdbWJ4J2_4Stpr7mrlJimbeQw'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Dari Nol Sampai Pro: Bikin Kalkulator dan Page Builder Interaktif Pakai HTML, CSS, JS!</h4>
</div>
</a>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/dari-nol-sampai-pro-panduan-lengkap.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_vG8Wayv4-T59T7jF9TjxOq7IkJp3DujH00L6w_g2xHEYAasuhTIRZg2q6iC6bz8jrmwB2FRsM7RNUK4pWDc3UcDNmsI4rQYiv2bdb3H47BbVf3mA'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Dari Nol Sampai Pro: Panduan Lengkap Simulasi Jaringan Pakai GNS3 dan Packet Tracer</h4>
</div>
</a>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/memaksimalkan-mikrotik-chr-panduan.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_vYHYVmjeTineVCgaec-lZZz5Jg3KDJWIZvmdJc8QKu2-7sQ3w95FHglrrS-5JzHSGAkxu7ZW2Ky54kGWhDIuX34ZyQeljgZcLdXOTu8wu9u4jw'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Memaksimalkan MikroTik CHR: Panduan Lengkap Manajemen Bandwidth dan Server Impianmu</h4>
</div>
</a>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/jago-jaringan-tanpa-nombok-hardware.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_taBw_Wx4JOO-MO8jLQFCNTrI7g1r9SN-DBo8pBi0sFQe0FaL4pRylMPI9HfaHvSBgOlkrdJrU6r13hYWFf9Vzdql6RZysCUkm6u6UEdDN3OUk2Qw'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Jago Jaringan Tanpa Nombok Hardware: Panduan Lengkap Simulasi dengan GNS3 dan Cisco Packet Tracer</h4>
</div>
</a>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/membangun-kalkulator-dan-page-builder.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_v9JcHTA5wK7PW-ySlTmBGBnI05_eWWKkkPHvZMgpG0r3CJglHld02tmTn0mfbecDkNen5u5kZg_gyuFt0LL0xGeb5M7FfKNaPqUMxdvg'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Membangun Kalkulator dan Page Builder Interaktif dengan HTML, CSS, dan JavaScript Murni</h4>
</div>
</a>
<a class='group flex gap-3 items-start' href='https://script.pintarapp.com/2026/03/bedah-solana-web3-panduan-lengkap.html'>
<div class='w-10 h-10 flex-shrink-0 bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border rounded-md overflow-hidden'>
<img class='w-full h-full object-cover transition-transform duration-500 group-hover:scale-110' loading='lazy' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_vRdzOefCV9wr3B_KjhZdgbuyeeduJblLfazmbk9_vswxVbzPqz7Z_yNKDrGau8GgcFBG2Cr1AyyvwbAjnepgPoMXrQdOcHoxpDfc7652phB2-G'/>
</div>
<div class='flex-1'>
<h4 class='text-xs font-semibold text-gray-800 dark:text-dark-text group-hover:text-blue-600 dark:group-hover:text-dark-link line-clamp-2 leading-snug'>Bedah Solana Web3: Panduan Lengkap Ngoding dApps dan Smart Contract dari Nol (Pakai Anchor, Bro!)</h4>
</div>
</a>
</div>
</div>
</div></div>
</aside>
</div>
</div>
<!-- FOOTER -->
<footer class='w-full border-t border-gray-200 dark:border-dark-border bg-gray-50 dark:bg-dark-900 mt-auto'>
<div class='max-w-[1200px] mx-auto px-4 py-6 flex flex-col md:flex-row justify-between items-center gap-4 text-xs text-gray-500 dark:text-dark-muted'>
<div class='flex items-center gap-2'>
<svg class='w-5 h-5 text-gray-400 dark:text-dark-muted' fill='currentColor' viewBox='0 0 24 24'><path clip-rule='evenodd' d='M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z' fill-rule='evenodd'></path></svg>
<span>© 2026 PintarApp Script. All rights reserved.</span>
</div>
<div class='flex space-x-4'>
<a class='hover:text-blue-600 dark:hover:text-dark-link transition-colors' href='/p/about.html#tentang'>About</a>
<a class='hover:text-blue-600 dark:hover:text-dark-link transition-colors' href='/p/about.html#privasi'>Privacy Policy</a>
<a class='hover:text-blue-600 dark:hover:text-dark-link transition-colors' href='/p/about.html#syarat'>Terms of Service</a>
</div>
</div>
</footer>
<!-- FLOATING SHARE (BOTTOM LEFT) -->
<div class='fixed bottom-20 md:bottom-6 left-4 md:left-6 z-50 flex flex-col items-center gap-3' id='floating-share'>
<div class='flex flex-col gap-3 opacity-0 invisible translate-y-4 transition-all duration-300' id='share-icons'>
<a class='w-10 h-10 rounded-full bg-white dark:bg-dark-800 border border-gray-200 dark:border-dark-border text-gray-700 dark:text-dark-text flex items-center justify-center hover:text-white hover:bg-[#1877F2] transition-colors shadow-lg' href='#' onclick='window.open("https://www.facebook.com/sharer.php?u="+encodeURIComponent(window.location.href), "_blank"); return false;'>
<svg class='w-5 h-5' fill='currentColor' viewBox='0 0 24 24'><path d='M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.469h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.469h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z'></path></svg>
</a>
<a class='w-10 h-10 rounded-full bg-white dark:bg-dark-800 border border-gray-200 dark:border-dark-border text-gray-700 dark:text-dark-text flex items-center justify-center hover:text-white hover:bg-[#25D366] transition-colors shadow-lg' href='#' onclick='window.open("https://api.whatsapp.com/send?text="+encodeURIComponent(document.title + " " + window.location.href), "_blank"); return false;'>
<svg class='w-5 h-5' fill='currentColor' viewBox='0 0 24 24'><path d='M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a12.8 12.8 0 00-.57-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z'></path></svg>
</a>
</div>
<button aria-label='Share' class='w-12 h-12 rounded-full bg-hacker-500 border border-transparent text-white flex items-center justify-center shadow-[0_4px_10px_rgba(35,134,54,0.4)] hover:bg-hacker-600 transition-colors' id='share-toggle-btn'>
<svg class='w-5 h-5 ml-[-2px]' fill='none' stroke='currentColor' viewBox='0 0 24 24'><path d='M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'></path></svg>
</button>
</div>
<!-- HIGHLIGHT.JS SCRIPT -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js'></script>
<script>hljs.highlightAll();</script>
<!-- CUSTOM LOGIC (SEARCH, SHARE, ADS, FETCHERS) -->
<script>
    //<![CDATA[
        document.addEventListener('DOMContentLoaded', () => {

            // Dark Mode Toggle Logic
            const themeToggleBtn = document.getElementById('theme-toggle');
            const darkIcon = document.getElementById('theme-toggle-dark-icon');
            const lightIcon = document.getElementById('theme-toggle-light-icon');

            if (darkIcon && lightIcon) {
                if (document.documentElement.classList.contains('dark')) {
                    lightIcon.classList.remove('hidden');
                } else {
                    darkIcon.classList.remove('hidden');
                }
            }

            function toggleTheme() {
                if (darkIcon) darkIcon.classList.toggle('hidden');
                if (lightIcon) lightIcon.classList.toggle('hidden');

                if (localStorage.getItem('color-theme')) {
                    if (localStorage.getItem('color-theme') === 'light') {
                        document.documentElement.classList.add('dark');
                        localStorage.setItem('color-theme', 'dark');
                    } else {
                        document.documentElement.classList.remove('dark');
                        localStorage.setItem('color-theme', 'light');
                    }
                } else {
                    if (document.documentElement.classList.contains('dark')) {
                        document.documentElement.classList.remove('dark');
                        localStorage.setItem('color-theme', 'light');
                    } else {
                        document.documentElement.classList.add('dark');
                        localStorage.setItem('color-theme', 'dark');
                    }
                }
            }

            if (themeToggleBtn) themeToggleBtn.addEventListener('click', toggleTheme);

            // Hamburger Mobile Menu Logic
            const mobileMenuBtn = document.getElementById('mobile-menu-btn');
            const mobileNavMenu = document.getElementById('mobile-nav-menu');
            if (mobileMenuBtn && mobileNavMenu) {
                mobileMenuBtn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    mobileNavMenu.classList.toggle('hidden');
                });
                document.addEventListener('click', (e) => {
                    if (!mobileNavMenu.contains(e.target) && !mobileMenuBtn.contains(e.target)) {
                        mobileNavMenu.classList.add('hidden');
                    }
                });
            }

            // 1. SEARCH TOGGLE LOGIC
            const searchBtn = document.getElementById('search-toggle');
            const searchBox = document.getElementById('search-box');
            if (searchBtn && searchBox) {
                searchBtn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    if (searchBox.classList.contains('opacity-0')) {
                        searchBox.classList.remove('opacity-0', 'invisible', 'translate-y-1');
                        searchBox.querySelector('input').focus();
                    } else {
                        searchBox.classList.add('opacity-0', 'invisible', 'translate-y-1');
                    }
                });
                document.addEventListener('click', (e) => {
                    if (!searchBox.contains(e.target) && !searchBtn.contains(e.target)) {
                        searchBox.classList.add('opacity-0', 'invisible', 'translate-y-1');
                    }
                });
            }

            // 2. FLOATING SHARE TOGGLE
            const shareBtn = document.getElementById('share-toggle-btn');
            const shareIcons = document.getElementById('share-icons');
            if (shareBtn && shareIcons) {
                shareBtn.addEventListener('click', () => {
                    shareIcons.classList.toggle('opacity-0');
                    shareIcons.classList.toggle('invisible');
                    shareIcons.classList.toggle('translate-y-4');
                });
            }

            // 3. AUTO INJECT COPY BUTTON TO PRE CODE
            document.querySelectorAll('pre').forEach(pre => {
                const btn = document.createElement('button');
                btn.className = 'copy-btn';
                btn.innerHTML = '<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path></svg> Copy';
                btn.onclick = () => {
                    const code = pre.querySelector('code');
                    if (code) {
                        navigator.clipboard.writeText(code.innerText).then(() => {
                            btn.innerHTML = '<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg> Copied!';
                            btn.classList.add('copied');
                            setTimeout(() => {
                                btn.innerHTML = '<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path></svg> Copy';
                                btn.classList.remove('copied');
                            }, 2000);
                        });
                    }
                };
                pre.appendChild(btn);
            });

            // 4. PARALLAX AD & IMAGE PROXY (Inside Post)
            const postBodies = document.querySelectorAll('.post-body');
            postBodies.forEach(body => {
                // Auto Photon Proxy for ibb
                const imgs = body.querySelectorAll('img');
                imgs.forEach(img => {
                    if (img.src && img.src.includes('ibb.co')) {
                        let cleanUrl = img.src.replace(/^https?:\/\//, '');
                        img.src = 'https://i0.wp.com/' + cleanUrl + '?quality=80&strip=all';
                    }
                });

                // Inject Parallax Ad at middle of post
                let pTags = body.querySelectorAll('br, p');
                if (pTags.length > 0) {
                    let mid = Math.floor(pTags.length / 2);
                    let target = pTags[mid];
                    if (target) {
                        const adHtml = '<div class="scriptParallax"><div class="ptx1"><div class="ptx2"><div class="flex justify-center items-center adsterra-slot w-[300px] h-[250px] lg:mr-[350px]" data-w="300" data-h="250" data-key="017ff5a2024d32a8d605ed757a4d6002"></div></div></div></div></div>';
                        target.insertAdjacentHTML('afterend', adHtml);
                    }
                }
            });

            // 5. FETCH DATA FOR HOMEPAGE MODULES
            if (document.getElementById('home-modules')) {
                fetchHomeModules();
            }

            // 6. ADSTERRA OBSERVER LAZY LOAD
            if ('IntersectionObserver' in window) {
                const adObserver = new IntersectionObserver((entries, observer) => {
                    entries.forEach(entry => {
                        if (entry.isIntersecting) {
                            const el = entry.target;
                            const k = el.getAttribute('data-key');
                            const w = el.getAttribute('data-w');
                            const h = el.getAttribute('data-h');
                            if (k && !el.hasAttribute('data-loaded')) {
                                el.setAttribute('data-loaded', 'true');
                                const iframe = document.createElement('iframe');
                                iframe.width = w; iframe.height = h; iframe.frameBorder = '0'; iframe.scrolling = 'no';
                                iframe.style.border = 'none'; iframe.style.overflow = 'hidden'; iframe.style.background = 'transparent';
                                iframe.style.margin = 'auto'; // Menggantikan absolute inset-0 agar tidak keluar jalur
                                el.appendChild(iframe);
                                const doc = iframe.contentWindow.document;
                                doc.open();
                                doc.write('<!DOCTYPE html><html><head><style>body{margin:0;padding:0;overflow:hidden;background:transparent;display:flex;justify-content:center;align-items:center;}</style></head><body>');
                                doc.write('<scr'+'ipt type="text/javascript">atOptions={"key":"'+k+'","format":"iframe","height":'+h+',"width":'+w+',"params":{}};</scr'+'ipt>');
                                doc.write('<scr'+'ipt type="text/javascript" src="https://www.highperformanceformat.com/'+k+'/invoke.js"></scr'+'ipt>');
                                doc.write('</body></html>');
                                doc.close();
                            }
                            observer.unobserve(el);
                        }
                    });
                }, { rootMargin: '200px' });

                document.querySelectorAll('.adsterra-slot').forEach(slot => adObserver.observe(slot));
            }
        });

        // === MOBILE TOP AD FUNCTIONS ===
        function minimizeMobileTopAd() {
            const ad = document.getElementById('mobile-top-ad');
            const btn = document.getElementById('show-mobile-top-ad-btn');
            if(ad && btn) {
                ad.style.transform = 'translateY(-100%)';
                setTimeout(() => { btn.classList.remove('hidden'); }, 300);
            }
        }
        function maximizeMobileTopAd() {
            const ad = document.getElementById('mobile-top-ad');
            const btn = document.getElementById('show-mobile-top-ad-btn');
            if(ad && btn) {
                ad.style.transform = 'translateY(0)';
                btn.classList.add('hidden');
            }
        }

        // === MOBILE BOTTOM STICKY AD FUNCTIONS ===
        function toggleMobileBottomAd() {
            const wrapper = document.getElementById('mobile-bottom-ad-wrapper');
            const icon = document.getElementById('bottom-ad-icon');
            // Jika posisinya di 0 (tampil), kita dorong ke bawah sejauh tingginya content (50px) + border (1px) = 51px
            if(wrapper.style.transform === 'translateY(0px)' || wrapper.style.transform === '') {
                wrapper.style.transform = 'translateY(51px)';
                icon.style.transform = 'rotate(180deg)'; // Panah naik
            } else {
                wrapper.style.transform = 'translateY(0px)';
                icon.style.transform = 'rotate(0deg)'; // Panah turun
            }
        }

        // === HOMEPAGE FETCHERS ===
        function fetchHomeModules() {
            // Fetch Sub Category 1 (List Style - Ex: Blogger)
            fetch('/feeds/posts/default/-/Blogger?alt=json&max-results=3')
            .then(res => res.json())
            .then(data => {
                let html = '';
                if(data.feed && data.feed.entry) {
                    data.feed.entry.forEach(post => {
                        const title = post.title.$t;
                        let link = post.link.find(l => l.rel === 'alternate')?.href || '#';
                        html += `<a href="${link}" class="flex gap-2 items-center group py-1">
                            <svg class="w-4 h-4 text-gray-400 dark:text-dark-muted group-hover:text-blue-600 dark:group-hover:text-dark-link transition-colors flex-shrink-0" fill="currentColor" viewBox="0 0 16 16"><path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path></svg>
                            <span class="text-blue-600 dark:text-dark-link group-hover:underline truncate">${title}</span>
                        </a>`;
                    });
                } else { html = '<span class="text-gray-500 dark:text-dark-muted">No scripts found.</span>'; }
                let container = document.getElementById('cat-blogger');
                if(container) container.innerHTML = html;
            }).catch(() => {});

            // Fetch Sub Category 2 (Grid Box Style - Ex: Tools)
            fetch('/feeds/posts/default/-/Tools?alt=json&max-results=4') 
            .then(res => res.json())
            .then(data => {
                let html = '';
                if(data.feed && data.feed.entry) {
                    data.feed.entry.forEach(post => {
                        const title = post.title.$t;
                        let link = post.link.find(l => l.rel === 'alternate')?.href || '#';
                        let snip = post.summary ? post.summary.$t : (post.content ? post.content.$t.replace(/<[^>]+>/g, '').substring(0, 60) + '...' : '');
                        html += `<a href="${link}" class="block bg-gray-50 dark:bg-dark-900 border border-gray-200 dark:border-dark-border p-4 rounded-md hover:border-gray-400 dark:hover:border-dark-muted transition-colors group">
                            <h3 class="text-blue-600 dark:text-dark-link font-semibold mb-1 group-hover:underline line-clamp-1">${title}</h3>
                            <p class="text-xs text-gray-500 dark:text-dark-muted line-clamp-2">${snip}</p>
                        </a>`;
                    });
                } else { html = '<span class="text-gray-500 dark:text-dark-muted">No data found.</span>'; }
                let container = document.getElementById('cat-tools');
                if(container) container.innerHTML = html;
            }).catch(() => {});
        }

        // Utility to extract images (incl. ImgBB to Photon)
        function extractThumb(post, w, h) {
            let thumbUrl = `https://via.placeholder.com/${w}x${h}/f3f4f6/9ca3af?text=[code]`;
            if (document.documentElement.classList.contains('dark')) {
                thumbUrl = `https://via.placeholder.com/${w}x${h}/161b22/30363d?text=[code]`;
            }
            if (post.media$thumbnail && post.media$thumbnail.url) {
                thumbUrl = post.media$thumbnail.url.replace(/\/s[0-9]+(\-c)?/, `/w${w}-h${h}-c`);
            } else if (post.content && post.content.$t) {
                const imgMatch = post.content.$t.match(/<img[^>]+src=['"]([^'"]+)['"]/i);
                if (imgMatch && imgMatch[1]) {
                    thumbUrl = imgMatch[1];
                    if (thumbUrl.includes('ibb.co')) {
                        let cleanUrl = thumbUrl.replace(/^https?:\/\//, '');
                        thumbUrl = `https://i0.wp.com/${cleanUrl}?resize=${w},${h}&quality=80&strip=all`;
                    }
                }
            }
            return thumbUrl;
        }
    //]]>
    </script>

</body>
</html>