Tutorial membuat BingChatAI API dengan Python dan Selenium

Cecep Aprilianto
6 min readDec 7, 2023

--

Kali ini kita akan membuat API dari result Bing Chat AI dengan Python dan Selenium Library. Bing.com sendiri mengeluarkan platform Chat atau percakapan yang interaktif dan terintegrasi dengan AI (Artificial Intelligence), sehingga kita bisa mendapatkan better result yang memuaskan dari kecerdasan buatan.

Perlu diketahui, Bing sendiri sampai tulisan ini dibuat, belum mengeluarkan API resmi Chat AI-nya untuk kita pakai. Jadi ini akan sedikit tricky untuk membuat API yang terintegrasi dengan Chat AI punya Bing ini.

Berikut gambaran AI Chat dari Bing.com

Bing Chat AI Form

Yang perlu kalian install:

  1. Chrome driver. Download disni, dan sesuaikan dengan versi Chrome dan OS yang ada di laptop kalian masing-masing. Kalau menggunakan MacOs, lebih mudah install dari homebrew, disini.
  2. Python. Download disni, gunakan versi terbaru.

Untuk melihat versi Chrome kalian, gunakan url ini ‘chrome://settings/help’ di browser dan akan tampil seperti gambar berikut:

Chrome Version

Membuat Projek

Ok, tanpa basa-basi, mari kita buat projeknya terlebih dahulu. Buat folder dengan nama bing-chat-ai, lalu gunakan perintah berikut untuk membuat python environment dengan virtualenv.

mkdir bing-chat-ai
cd bing-chat-ai
python3 -m venv bing-env

Kemudian, aktifkan environment tadi dengan perintah berikut (untuk linux atau macos):

source bing-env/bin/activate

Setelah virtual env aktif, kita akan meng-install package atau library yang dibutuhkan dengan perintah berikut:

pip install selenium fastapi "uvicorn[standard]"

Lalu buka projek kalian dengan Code Editor favorit masing-masing. Disini saya menggunakan PyCharm. Download disini.

Buat file bernama main.py, dan isi dengan kode awal seperti berikut:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
return {"result": "Welcome"}

Kode di atas untuk memastikan API yang akan kita buat sudah berjalan dengan benar. Buka kembali terminal, dan jalankan perintah berikut:

uvicorn main:app --reload

Untuk mengetahui API nya sudah berjalan, kita coba dengan curl, seperti berikut:

 curl -X GET http://127.0.0.1:8000

Jika muncul `{“result”:”Welcome”}`, maka API sudah berjalan seperti yang diharapkan.

Membuat bot dengan Selenium

Pertama, kita breakdown 1/1 setiap langkah yang dibutuhkan untuk men-scraping website bing.com, khususya pada page Chat AI nya. Buat file bernama bing.py, lalu isi kode awal & selanjutnya seperti berikut:

# filename: bing.py
# import the required packages
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.remote.shadowroot import ShadowRoot
from selenium.webdriver.remote.webdriver import WebElement
from selenium.webdriver.common.keys import Keys
import time

Seting Web Driver

Ok, langkah selanjutnya yaitu membuat variable driver yang di setting untuk Chrome, kodenya seperti berikut:

options = webdriver.ChromeOptions()
options.add_argument('--headless=new')
options.add_argument('--no-sandbox')

# Tentukan lokasi chromedriver kalian disini
service = Service("/opt/homebrew/bin/chromedriver")

driver = webdriver.Chrome(service=service, options=options)
driver.set_window_size(width=1500, height=1000)

Pada kode di atas, kalian akan melihat argumen headless yang diberikan pada ChomeOptions adalah ‘ — headless=new’. Ini menggunakan versi baru Chrome headless yang diumumkan awal tahun ini (Baca disini).

Chrome headless dulunya merupakan implementasi terpisah dari implementasi headful. Terkadang menyebabkan ketidakkonsistenan pada hasil test saat menggunakan Selenium untuk testing aplikasi. Sekarang basis kode headless dan headful disatukan. Saat ini, jika kalian hanya menggunakan argumen ‘ — headless’, maka akan menggunakan implementasi headless yang lama.

Matikan pengaturan SafeSearch

Di bing chat sendiri, untuk memakai chat AI kita harus seting SafeSearch menjadi off agar bisa masuk ke halaman chat nya. Jadi, langkah selanjutnya yaitu, kita akan buka halaman seting lalu simulasi klik pengaturan SafeSearch menjadi off, lalu save dan agree pengaturannya. Kodenya seperti berikut:

driver.get("https://www.bing.com/account/general")
driver.find_element(By.XPATH, '//*[@id="adlt_set_off"]').click()
time.sleep(1)

driver.find_element(By.XPATH, '//*[@id="sv_btn"]').click()
time.sleep(1)

driver.find_element(By.XPATH, '//*[@id="adlt_confirm"]').click()
time.sleep(1)

Time sleep 1 detik digunakan agar simulasinya tidak terlalu cepat dan dianggap human bukan bot oleh bing. Kurang lebih, simulasinya akan seperti berikut:

Setting SafeSearch to Off

Navigasi ke halaman Chat

Selanjutnya, setelah pengaturan berhasil di off, kita akan menavigasi langsung ke halaman chat. Kodenya seperti berikut:

driver.get("https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx")
time.sleep(10)
driver.save_screenshot("bing-chat-page.png")

Time sleep 10 detik untuk memastikan bahwa form untuk memasukkan pertanyaan sudah muncul dengan baik, dan kita simpan screenshotnya juga untuk memastikan apakah halamannya benar. Berikut hasil save screenshotnya:

Screenshot chat page

Proses input pertanyaan

Selanjutnya, kita akan breakdown dulu frame untuk menampilkan form input pertanyaan dengan cara mengambil css selector dari setiap frame, dengan cara klik kanan dari frame yang akan di ambil lalu pilih copy lalu pilih selector (sebelumnya masuk ke developer console dengan cara tekan f12, dan pilih tab Elements).

Hal ini dikarenakan tag-tag yang dipakai tidak langsung ada didalam DOM, melainkan di encapsulasi dengan shadow tree, jadi kita perlu masuk kedalam frame tersebut dan mengambil shadowRoot propertynya.

Berikut ini kode dan gambar dari setiap frame:

Gambar Frame 1:

Frame 1

Kode Frame 1:

cib_serp_el = driver.find_element(By.CSS_SELECTOR, '#b_sydConvCont > cib-serp')
shadow_root_cib_serp: ShadowRoot = driver.execute_script("return arguments[0].shadowRoot;", cib_serp_el)

Gambar Frame 2:

Frame 2

Kode Frame 2:

cib_action_bar_el = shadow_root_cib_serp.find_element(By.CSS_SELECTOR, '#cib-action-bar-main')
shadow_root_cib_action_bar: ShadowRoot = driver.execute_script("return arguments[0].shadowRoot;", cib_action_bar_el)

Gambar Frame 3:

Frame 3

Kode Frame 3:

cib_text_input_el = shadow_root_cib_action_bar.find_element(By.CSS_SELECTOR, 'div > div.main-container > div > div.input-row > cib-text-input')
shadow_root_cib_text_input: ShadowRoot = driver.execute_script("return arguments[0].shadowRoot;", cib_text_input_el)

Setelah masuk kedalam setiap frame, selanjutnya kita akan simulasi input pertanyaan dengan kode berikut:

input_prompt_el: WebElement = shadow_root_cib_text_input.find_element(By.CSS_SELECTOR, '#searchbox')

# masukkan pertanyaan disini
input_prompt_el.send_keys("Selamat pagi, apa kabar?")
input_prompt_el.send_keys(Keys.ENTER)
time.sleep(5)

Time sleep 5 detik ini perlu di atur lagi agar menyesuaikan dengan proses lama jawabannya akan dihasilkan.

Proses mendapatkan teks jawaban

Setelah proses input pertanyaan selesai dan berhasil, selanjutnya kita akan mengambil teks jawaban dari hasil generate oleh Bing Chat AI.

Kurang lebih prosesnya akan sama dengan proses input pertanyaan, dimana kita harus masuk terlebih dahulu ke setiap frame untuk mendapatkan element yang menghasilkan jawabannya.

Kodenya seperti berikut:

cib_conversation = shadow_root_cib_serp.find_element(By.CSS_SELECTOR, '#cib-conversation-main')
shadow_root_cib_conversation: ShadowRoot = driver.execute_script("return arguments[0].shadowRoot;", cib_conversation)

cib_chat_turn_el = shadow_root_cib_conversation.find_element(By.CSS_SELECTOR, '#cib-chat-main > cib-chat-turn')
shadow_root_cib_chat_turn: ShadowRoot = driver.execute_script("return arguments[0].shadowRoot;", cib_chat_turn_el)

cib_message_group_el = shadow_root_cib_chat_turn.find_element(By.CSS_SELECTOR, 'cib-message-group.response-message-group')
WebDriverWait(driver, 10).until(EC.visibility_of(cib_message_group_el), "Timeout cib-message-group.response-message-group")
shadow_root_cib_message_group: ShadowRoot = driver.execute_script("return arguments[0].shadowRoot;", cib_message_group_el)

cib_message_el = shadow_root_cib_message_group.find_element(By.CSS_SELECTOR, 'cib-message')
shadow_root_cib_message: ShadowRoot = driver.execute_script("return arguments[0].shadowRoot;", cib_message_el)

# save screenshot untuk memastikan apakah benar gambaran prosesnya
driver.save_screenshot("bing-cib-message.png")

cib_shared_el: WebElement = shadow_root_cib_message.find_element(By.CSS_SELECTOR, 'cib-shared')
WebDriverWait(driver, 10).until(EC.visibility_of(cib_shared_el), "Timeout cib-shared")

# get text content
print("result:", cib_shared_el.text)

Save screenshot untuk memastikan apakah benar gambaran prosesnya. ada juga WebDriverWait, untuk memastikan element yang kita ingin dapatkan tampil atau terlihat di DOM.

Masukkan baris kode berikut di baris akhir untuk menutup koneksi browser:

driver.quit()

Untuk final touch, buat kodenya dalam fungsi dengan parameter question, seperti berikut:

def bot(question: str) -> str:
# tempel disini kode yang sudah dibuat
# gantikan baris kode berikut adgar menerima parameter 'question'
# input_prompt_el.send_keys("Selamat pagi, apa kabar?")
input_prompt_el.send_keys(question)

...

Membuat endpoint chat

Selanjutnya, kita akan membuat endpoint chat yang akan digunakan untuk request berdasarkan pertanyaan yang akan di input.

Buka kembali file main.py, dan isikan dengan kode berikut:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import bing
from bing import WebDriverException

app = FastAPI()


class ChatRequest(BaseModel):
question: str


@app.get("/")
def read_root():
return {"result": "Welcome"}


@app.post("/chat")
async def chat(req: ChatRequest):
try:
answer = bing.bot(req.question)
except WebDriverException as e:
raise HTTPException(status_code=500, detail=f"Bot error WebDriverException: {e}")
except Exception as e:
raise HTTPException(status_code=500, detail=f"Bot error: {e}")

return {"result": answer}

Jalankan pada terminal dengan perintah berikut:

uvicorn main:app --reload

Setelah berhasil di jalankan, kita coba endpoint yang baru dengan curl berikut:

curl -X POST http://127.0.0.1:8000/chat -H 'Content-Type: application/json' -d '{"question": "Selamat pagi, apa kabar?"}'

Jika berhasil, maka akan muncul response json seperti berikut:

{"result":"Selamat pagi! Saya Bing. Saya baik-baik saja, terima kasih. Bagaimana kabarmu? Apakah ada yang bisa saya bantu?"}

Untuk membuktikan responsenya benar, buka hasil save screenshot ‘bing-cib-message.png’ ✨

bing-cib-message.png

Jika terlihat sama, maka kita sudah sukses membuat bot Bing Chat AI. 👏

Download Source Code

Kalian bisa download full codenya di github 🤡

--

--