Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
nodriver — Undetected-Chromedriver의 후속작입니다. Captcha / CloudFlare / Imperva / hCaptcha와 같은 성가신 안티 봇 시스템에 의해 일반적으로 방해받는 웹 자동화, 웹스크래핑, 봇 및 기타 창의적인 아이디어를 위한 초고속 프레임워크를 제공합니다. | Kitploit
도구/GitHubGitHub/ultrafunkamsterdam/nodriver
Phishing ToolsWeb Proxies & InterceptionIDS/IPS EvasionImpersonation ToolsScripting & AutomationWAF BypassWeb SecurityCrawlerAnti-BotFingerprint SpoofingCAPTCHA Bypass
4.6k43013개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
GitHub
ultrafunkamsterdam/nodriver

nodriver

Undetected-Chromedriver의 후속작입니다. Captcha / CloudFlare / Imperva / hCaptcha와 같은 성가신 안티 봇 시스템에 의해 일반적으로 방해받는 웹 자동화, 웹스크래핑, 봇 및 기타 창의적인 아이디어를 위한 초고속 프레임워크를 제공합니다.

저장소 보기

NODRIVER

nodriver는 파이썬을 위한 차세대 비동기 웹 스크래핑 및 브라우저 자동화 라이브러리로, 쉽고 그냥 말이 되는(Just Makes Sense ™) 인터페이스를 제공합니다.

  • 이것은 Undetected-Chromedriver 파이썬 패키지의 공식 후속작입니다.
  • 더 이상 webdriver도, selenium도 필요 없습니다.

문서는 여기를 클릭하세요

직접 통신은 웹 애플리케이션 방화벽(WAF)에 대해 훨씬 더 강한 저항성을 제공하며, 성능도 대폭 향상됩니다. 이 모듈은 undetected-chromedriver와 달리 완전히 비동기(async) 방식입니다.

이 패키지를 다른 알려진 패키지들과 차별화하는 점은 대부분의 안티봇(anti-bot) 솔루션에서 탐지되지 않도록 최적화되어 있다는 것입니다.

또 다른 핵심 포인트는 사용성과 빠른 프로토타이핑입니다. 따라서 대부분의 메서드 매개변수에 모범 사례(best practice) 기본값이 설정되어 있어 많은 것들이 -있는 그대로- 작동할 것으로 기대하세요.

1~2줄이면 실행되며, 기본적으로 모범 사례 구성을 제공합니다. 작업 후에는 생성된 파일(프로필)을 정리합니다.

다음에서 작동하는 것으로 알려져 있습니다.

  • chromium
  • chrome
  • edge
  • brave

사용성과 편의성도 중요하지만, CDP 도메인, 메서드, 이벤트의 전체 배열을 사용하여 모든 것을 완전히 사용자 정의하는 것도 쉽습니다.

주요 기능

  • chromedriver 바이너리나 Selenium 의존성 없음

  • 코드 한 줄로 바로 실행 가능*

  • 실행할 때마다 새 프로필을 사용하고, 종료 시 정리함

  • 쿠키를 파일로 저장하고 불러와서 번거로운 로그인 절차를 반복하지 않음

  • tab.find("sometext")

    tab.find_all("sometext")

    tab.select("a[class*=something]")

    tab.select_all("a[href] > div > img")

    셀렉터 또는 텍스트로 요소를 찾는 스마트하고 효율적인 요소 검색을 제공하며, iframe 콘텐츠도 포함합니다. 이 기능은 요소가 나타날 때까지 시간 동안 재시도하므로, 요소가 나타나기를 기다리는 조건으로도 사용할 수 있습니다. 따라서 await tab.select('body')는 페이지 로드 여부를 나타내는 지표로 사용될 수 있습니다. find 메서드는 텍스트로 검색하지만, 단순히 첫 번째 일치 요소를 반환하지 않고 텍스트 길이가 가장 가까운 후보를 매칭합니다(가장 짧은 텍스트가 우선). 이렇게 하면 tab.find('accept all') 같은 조회가 헤더의 스크립트를 반환하는 대신 실제 쿠키 버튼을 반환하게 됩니다.

  • 실행 중인 chrome 디버그 세션에 연결 가능

  • 요소를 html로 표현하는 설명적인 __repr__ 제공

  • 실행 중인 undetected_chromedriver.Chrome 인스턴스를 nodriver.Browser 인스턴스로 변환하여 그대로 계속 작업할 수 있는 유틸리티 함수 제공

  • 가장 많이 사용되고 중요한 작업을 위한 헬퍼 및 유틸리티 메서드가 가득 포함됨

새로운 기능

0.50.1 플랫 모드 연결로 전환

프로토콜에서 플랫 연결을 사용하도록 일부 파트가 다시 작성되었습니다. 왜? - 대부분의 작업에 iframe이 포함됩니다. - 탭에 새로운 메서드가 추가되었습니다: await tab.get_frames() 검사 가능한 Iframe을 반환합니다. - find()는 iframe을 포함하므로 "verify you are human"을 검색하고 js 챌린지의 인증 체크박스를 클릭할 수도 있습니다.

이번 변경은 상당한 재작성이 필요했으므로, 특히 대규모 프로젝트를 운영 중이라면 철저히 테스트해 주세요.

tab.xpath(selector, timeout=2.5)

xpath 셀렉터를 사용하여 노드를 찾습니다! api 문서의 tab xpath를 참조하세요.

tab.cf_verify()

체크박스를 찾아 성공적으로 클릭합니다. 이 기능은 expert 모드가 아닐 때만 작동합니다. 현재는 영어만 내장되어 있습니다. opencv-python 패키지가 설치되어 있어야 합니다.

tab.bypass_insecure_connection_warning()

안전하지 않은 페이지 경고를 처리하기 위한 편의 메서드입니다. 예를 들어 인증서가 유효하지 않은 경우입니다.

tab.open_external_debugger()

연결을 끊지 않고 탭을 검사할 수 있게 해 줍니다.

tab.get_local_storage()

localstorage 콘텐츠 가져오기

tab.set_local_storage(dict)

localstorage 콘텐츠 설정

tab.add_handler(someEvent, callback)

callback은 단일 인자(event) 또는 2개의 인자(event, tab)를 받을 수 있습니다.

start(expert=True)

보다 숙련된 사용자를 위한 몇 가지 해킹을 수행합니다. 웹 보안과 origin-trials를 비활성화하고, shadow-roots가 항상 열려 있도록 보장합니다. 다만 이렇게 하면 탐지될 가능성이 더 높아집니다!

설치

이 패키지를 사용하는 머신에 chrome(또는 일부 chromium 기반 브라우저)이 설치되어 있어야 하며, 가급적 기본 위치에 설치하는 것이 좋습니다.

디스플레이가 없는 AWS 또는 기타 환경과 같은 헤드리스 머신에서 실행할 때는 **화면(screen)**을 에뮬레이션하기 위해 Xvfb 도구를 사용하는 것이 가장 좋습니다. 대안으로 이 패키지는 헤드리스 모드로도 사용할 수 있습니다.

pip를 사용하여 nodriver를 설치할 수 있습니다

root@kitploit:~
pip install nodriver

업데이트하려면

root@kitploit:~
pip install -U nodriver

사용 예제

이 프로젝트의 목표는 (아주 오래전 undetected-chromedriver와 마찬가지로) 짧고 단순하게 유지하는 것입니다. 그래서 에디터나 인터랙티브 세션을 빠르게 열고, 몇 줄을 입력하거나 붙여넣으면 바로 실행할 수 있습니다.

간단한 예

root@kitploit:~
import nodriver as uc

async def main():

    browser = await uc.start()
    page = await browser.get('https://www.nowsecure.nl')

    ... further code ...

if __name__ == '__main__':
    # since asyncio.run never worked (for me)
    uc.loop().run_until_complete(main())

사용자 지정 시작 옵션

여기서는 async 보일러플레이트는 생략하겠습니다.

root@kitploit:~
from nodriver import *

browser = await start(
    headless=False,
    user_data_dir="/path/to/existing/profile",  # by specifying it, it won't be automatically cleaned up when finished
    browser_executable_path="/path/to/some/other/browser",
    browser_args=['--some-browser-arg=true', '--some-other-option'],
    lang="en-US"   # this could set iso-language-code in navigator, not recommended to change
)
tab = await browser.get('https://somewebsite.com')

Config 객체를 사용한 사용자 지정 옵션

여기서는 async 보일러플레이트는 생략하겠습니다.

root@kitploit:~
from nodriver import *

config = Config()
config.headless = False
config.user_data_dir="/path/to/existing/profile",  # by specifying it, it won't be automatically cleaned up when finished
config.browser_executable_path="/path/to/some/other/browser",
config.browser_args=['--some-browser-arg=true', '--some-other-option'],
config.lang="en-US"   # this could set iso-language-code in navigator, not recommended to change
)

몇 가지 예시

root@kitploit:~
import nodriver

async def main():

    browser = await nodriver.start()
    page = await browser.get('https://www.nowsecure.nl')

    await page.save_screenshot()
    await page.get_content()
    await page.scroll_down(150)
    elems = await page.select_all('*[src]')

    for elem in elems:
        await elem.flash()

    page2 = await browser.get('https://twitter.com', new_tab=True)
    page3 = await browser.get('https://github.com/ultrafunkamsterdam/nodriver', new_window=True)

    for p in (page, page2, page3):
       await p.bring_to_front()
       await p.scroll_down(200)
       await p   # wait for events to be processed
       await p.reload()
       if p != page3:
           await p.close()

if __name__ == '__main__':

    # since asyncio.run never worked (for me)
    uc.loop().run_until_complete(main())

전체 코드 예제

Twitter/X 계정 생성 자동화

root@kitploit:~

A more concrete example, which can be found in the ./example/ folder,
shows a script to create a twitter account

```python
import random
import string
import logging

logging.basicConfig(level=30)

import nodriver as uc

months = [
    "january",
    "february",
    "march",
    "april",
    "may",
    "june",
    "july",
    "august",
    "september",
    "october",
    "november",
    "december",
]


async def main():
    driver = await uc.start()

    tab = await driver.get("https://twitter.com")

    # wait for text to appear instead of a static number of seconds to wait
    # this does not always work as expected, due to speed.
    print('finding the "create account" button')
    create_account = await tab.find("create account", best_match=True)

    print('"create account" => click')
    await create_account.click()

    print("finding the email input field")
    email = await tab.select("input[type=email]")

    # sometimes, email field is not shown, because phone is being asked instead
    # when this occurs, find the small text which says "use email instead"
    if not email:
        use_mail_instead = await tab.find("use email instead")
        # and click it
        await use_mail_instead.click()

        # now find the email field again
        email = await tab.select("input[type=email]")

    randstr = lambda k: "".join(random.choices(string.ascii_letters, k=k))

    # send keys to email field
    print('filling in the "email" input field')
    await email.send_keys("".join([randstr(8), "@", randstr(8), ".com"]))

    # find the name input field
    print("finding the name input field")
    name = await tab.select("input[type=text]")

    # again, send random text
    print('filling in the "name" input field')
    await name.send_keys(randstr(8))

    # since there are 3 select fields on the tab, we can use unpacking
    # to assign each field
    print('finding the "month" , "day" and "year" fields in 1 go')
    sel_month, sel_day, sel_year = await tab.select_all("select")

    # await sel_month.focus()
    print('filling in the "month" input field')
    await sel_month.send_keys(months[random.randint(0, 11)].title())

    # await sel_day.focus()
    # i don't want to bother with month-lengths and leap years
    print('filling in the "day" input field')
    await sel_day.send_keys(str(random.randint(0, 28)))

    # await sel_year.focus()
    # i don't want to bother with age restrictions
    print('filling in the "year" input field')
    await sel_year.send_keys(str(random.randint(1980, 2005)))

    await tab

    # let's handle the cookie nag as well
    cookie_bar_accept = await tab.find("accept all", best_match=True)
    if cookie_bar_accept:
        await cookie_bar_accept.click()

    await tab.sleep(1)

    next_btn = await tab.find(text="next", best_match=True)
    # for btn in reversed(next_btns):
    await next_btn.mouse_click()

    print("sleeping 2 seconds")
    await tab.sleep(2)  # visually see what part we're actually in

    print('finding "next" button')
    next_btn = await tab.find(text="next", best_match=True)
    print('clicking "next" button')
    await next_btn.mouse_click()

    # just wait for some button, before we continue
    await tab.select("[role=button]")

    print('finding "sign up"  button')
    sign_up_btn = await tab.find("Sign up", best_match=True)
    # we need the second one
    print('clicking "sign up"  button')
    await sign_up_btn.click()

    print('the rest of the "implementation" is out of scope')
    # further implementation outside of scope
    await tab.sleep(10)
    driver.stop()

    # verification code per mail


if __name__ == "__main__":
    # since asyncio.run never worked (for me)
    # i use
    uc.loop().run_until_complete(main())

더 많은 예제는 ./example/ 폴더에 있습니다

도구 다운로드