웹 브라우저 자동화 에이전트
웹 브라우저 자동화 에이전트 🤖🌐
출처: Web Browser Automation with Agents — Hugging Face smolagents 공식 문서
이 노트북에서는 에이전트가 동작하는 웹 브라우저 자동화 시스템을 만들어 볼게요. 이 시스템은 웹사이트를 탐색하고, 요소를 클릭하고, 정보를 자동으로 추출할 수 있어요.
에이전트는 이런 일을 할 수 있어요:
- 웹 페이지로 이동하기
- 요소 클릭하기
- 페이지 안에서 검색하기
- 팝업과 모달 처리하기
- 정보 추출하기
이 시스템을 단계별로 구성해 볼게요!
먼저 필요한 의존성을 설치하기 위해 아래 줄을 실행해요.
pip install smolagents selenium helium pillow -q
필요한 라이브러리를 불러오고 환경 변수를 설정해요.
from io import BytesIO
from time import sleep
import helium
from dotenv import load_dotenv
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from smolagents import CodeAgent, tool
from smolagents.agents import ActionStep
# 환경 변수 로드
load_dotenv()
이제 에이전트가 웹 페이지를 탐색하고 상호작용할 수 있는 핵심 브라우저 상호작용 도구를 만들어요.
@tool
def search_item_ctrl_f(text: str, nth_result: int = 1) -> str:
"""
Ctrl + F로 현재 페이지에서 텍스트를 검색하고 n번째 항목으로 이동합니다.
Args:
text: 검색할 텍스트
nth_result: 이동할 항목 번호 (기본: 1)
"""
elements = driver.find_elements(By.XPATH, f"//*[contains(text(), '{text}')]")
if nth_result > len(elements):
raise Exception(f"Match n°{nth_result} not found (only {len(elements)} matches found)")
result = f"Found {len(elements)} matches for '{text}'."
elem = elements[nth_result - 1]
driver.execute_script("arguments[0].scrollIntoView(true);", elem)
result += f"Focused on element {nth_result} of {len(elements)}"
return result
@tool
def go_back() -> None:
"""이전 페이지로 돌아갑니다."""
driver.back()
@tool
def close_popups() -> str:
"""
페이지에 보이는 모달이나 팝업을 닫습니다. 팝업 창을 닫을 때 사용하세요!
쿠키 동의 배너에는 작동하지 않습니다.
"""
webdriver.ActionChains(driver).send_keys(Keys.ESCAPE).perform()
Chrome으로 브라우저를 설정하고 스크린샷 기능을 구성해요.
# Chrome 옵션 구성
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--force-device-scale-factor=1")
chrome_options.add_argument("--window-size=1000,1350")
chrome_options.add_argument("--disable-pdf-viewer")
chrome_options.add_argument("--window-position=0,0")
# 브라우저 초기화
driver = helium.start_chrome(headless=False, options=chrome_options)
# 스크린샷 콜백 설정
def save_screenshot(memory_step: ActionStep, agent: CodeAgent) -> None:
sleep(1.0) # 스크린샷을 찍기 전에 JavaScript 애니메이션이 끝나도록 대기
driver = helium.get_driver()
current_step = memory_step.step_number
if driver is not None:
for previous_memory_step in agent.memory.steps: # 처리를 가볍게 하기 위해 이전 스크린샷 제거
if isinstance(previous_memory_step, ActionStep) and previous_memory_step.step_number <= current_step - 2:
previous_memory_step.observations_images = None
png_bytes = driver.get_screenshot_as_png()
image = Image.open(BytesIO(png_bytes))
print(f"Captured a browser screenshot: {image.size} pixels")
memory_step.observations_images = [image.copy()] # 유지되도록 복사본 생성
# 현재 URL로 관찰 내용 업데이트
url_info = f"Current url: {driver.current_url}"
memory_step.observations = (
url_info if memory_step.observations is None else memory_step.observations + "\n" + url_info
)
이제 웹 자동화 에이전트를 만들어요.
from smolagents import InferenceClientModel
# 모델 초기화
model_id = "Qwen/Qwen2-VL-72B-Instruct" # 원하는 VLM 모델로 바꿔도 됩니다
model = InferenceClientModel(model_id=model_id)
# 에이전트 생성
agent = CodeAgent(
tools=[go_back, close_popups, search_item_ctrl_f],
model=model,
additional_authorized_imports=["helium"],
step_callbacks=[save_screenshot],
max_steps=20,
verbosity_level=2,
)
# 에이전트용으로 helium import
agent.python_executor("from helium import *", agent.state)
에이전트는 웹 자동화를 위해 Helium을 어떻게 쓰는지 지침이 필요해요. 우리가 제공할 지침은 이렇습니다.
helium_instructions = """
You can use helium to access websites. Don't bother about the helium driver, it's already managed.
We've already ran "from helium import *"
Then you can go to pages!
Code:
```py
go_to('github.com/trending')
```<end_code>
You can directly click clickable elements by inputting the text that appears on them.
Code:
```py
click("Top products")
```<end_code>
If it's a link:
Code:
```py
click(Link("Top products"))
```<end_code>
If you try to interact with an element and it's not found, you'll get a LookupError.
In general stop your action after each button click to see what happens on your screenshot.
Never try to login in a page.
To scroll up or down, use scroll_down or scroll_up with as an argument the number of pixels to scroll from.
Code:
```py
scroll_down(num_pixels=1200) # This will scroll one viewport down
```<end_code>
When you have pop-ups with a cross icon to close, don't try to click the close icon by finding its element or targeting an 'X' element (this most often fails).
Just use your built-in tool `close_popups` to close them:
Code:
```py
close_popups()
```<end_code>
You can use .exists() to check for the existence of an element. For example:
Code:
```py
if Text('Accept cookies?').exists():
click('I accept')
```<end_code>
"""
이제 에이전트를 작업과 함께 실행할 수 있어요. 위키백과에서 정보를 찾아보는 예를 시도해 볼게요.
search_request = """
Please navigate to https://en.wikipedia.org/wiki/Chicago and give me a sentence containing the word "1992" that mentions a construction accident.
"""
agent_output = agent.run(search_request + helium_instructions)
print("Final output:")
print(agent_output)
요청을 수정해 다른 작업을 실행할 수도 있어요. 예를 들어 제가 더 열심히 일해야 하는지 알아보는 작업이에요.
github_request = """
I'm trying to find how hard I have to work to get a repo in github.com/trending.
Can you navigate to the profile for the top author of the top trending repo, and give me their total number of commits over the last year?
"""
agent_output = agent.run(github_request + helium_instructions)
print("Final output:")
print(agent_output)
이 시스템은 이런 작업에 특히 효과적이에요:
- 웹사이트에서 데이터 추출
- 웹 리서치 자동화
- UI 테스트와 검증
- 콘텐츠 모니터링