일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 퍼피티어
- nginx
- 예매
- fiddler
- Django
- 자동화 도구
- 프록시
- WSL
- 개발자 도구
- 직링
- 티켓
- 일렉트론
- puppeteer
- AWS
- ubuntu
- selenium
- 티켓링크
- App
- FastAPI
- uvicorn
- 피들러
- kotlin
- 개발자 도구 우회
- 자동화
- linux
- realtime
- EC2
- GPT
- 콘서트
- WebRTC
- Today
- Total
개발 삽질 일지
[직링 개발자 도구] 사용자 동작을 흉내 내서 콘서트 예매하기 본문
지난 글에서는 Netfunnel에 대한 간단한 소개와, 직링으로 접속 시 "잘못된 접근입니다."라는 오류 메시지가 뜨지 않게하는 우회 방법들을 소개해드렸습니다. 하지만 지금은 콘솔창과 크롬 익스텐션 만으로는 뚫을 수 없다는 결론에 이르렀습니다. 줄을 건너뛰지 못한다면, 줄 제일 앞에 서는 방법을 찾아야죠. 이번 글에서는 실제 사용자의 동작을 흉내 내는 방식을 소개해드릴려고 합니다.
⚠️ 이 글은 기술적인 호기심과 실험적인 분석을 위한 목적으로 작성되었습니다. 실제 예매 과정에서 이를 악용하거나 무단으로 활용하는 것은 서비스 약관 위반이 될 수 있으며, 법적 책임이 따를 수 있습니다. 또한, 이번 글에서는 코드 구현보다는 개념과 작동 원리에 집중하니 가볍게 읽어주시길 바랍니다.
콘솔과 크롬 익스텐션으로 사용자 흉내내기
우선 쉬운 방법부터 진행해봅시다. 개발자 도구(F12)를 누르고, Elements 혹은 요소탭에서 클릭해야 하는 버튼(날짜/시간 등)을 ctrl + shift + c 혹은 가장 좌측에 있는 화살표 모양을 눌러서 가져다가 대봅시다.
개발자 도구가 안켜지는 사이트의 경우에는 ctrl + shift + i 혹은 위와 동일한 입력으로 개발자 도구를 사용할 수 있습니다. (이런 경우 F12를 감지하고, 작동하지 못하게 막아둔 것입니다.) 새 창을 띄워서 개발자 도구를 보실 분들은 우측에 점 세개 아이콘 클릭 후, 맨 처음에 있는 Dock을 클릭해주시면 됩니다.
그럼 이제 날짜를 클릭해봅시다. 날짜 버튼 HTML을 확인해보고 전/후 비교를 해봅시다.
<button data-day="20250522" class=sample_date> 2025년 5월 22일 </button>
<button data-day="20250522" class=sample_date selected> 2025년 5월 22일 </button>
위 코드는 임의로 작성한 예시 코드입니다. 하지만 마우스를 클릭하는 순간 HTML이 바뀌는 것을 쉽게 확인하실 수 있을거라고 생각합니다. 꼭 버튼이 아니더라도 버튼을 감싸고 있는 요소의 값이 바뀌는 경우도 있습니다. 그러면 저 버튼을 클릭하는 코드를 작성해봅시다.
const date_btn = document.querySelector(".sample_date")
date_btn.click()
date_btn은 문서에서 sample_date라는 클래스를 가진 요소입니다. class가 아니라 id인 경우에는 getElementbyId("sample_date")로 해주시면 됩니다. 이후, date_btn을 클릭해줍니다. 사용자 흉내를 완전하게 내기 위해서는 HTML에 클래스가 추가되는 것 뿐만 아니라 개발자 도구의 Network, 혹은 네트워크 탭도 확인을 해주어야 합니다.
실제로 버튼을 클릭한 경우와, 콘솔 창에 코드를 입력하여 클릭했을 때, 동일하게 작동했음을 확인할 수 있습니다. 날짜 선택은 문제 없이 넘어갔네요. 여러 콘서트들을 찾아본 결과 하루에 한개의 콘서트만 열리는 경우가 많았습니다.(날짜 선택 시 시간 자동 선택된다는 뜻입니다.) 그렇다면 다음은 예매하기 버튼입니다.
정상적인 방법으로 예매하기 버튼을 클릭했을 때, 네트워크 탭입니다. 위에 3개 중 identity-는 사용자 확인, buyBtnClick은 예매하기 버튼 클릭, 그리고 마지막은 토큰을 제공해줍니다. 그렇다면 콘솔을 통해서 예매하기 버튼을 클릭해보도록 하겠습니다. 아래는 예시 코드입니다.
// 날짜 선택
const date_btn = document.querySelector(".sample_date")
date_btn.click()
const buy_btn = document.querySelector(".buy_ticket")
buy_btn.click()
날짜가 바뀌는걸 UI로 확인했는데 예매하기 버튼은 눌러도 네트워크 탭에서 새로운 요청이 감지되지 않습니다. btn.click()은 요소에 직접적으로 클릭 이벤트를 실행하는 JavaScript 함수입니다. 하지만 이건 어디까지나 프로그래밍적으로 클릭했다는 신호일 뿐, 브라우저가 클릭한 것 처럼 모든 처리를 해주지는 않습니다. 예시를 들어보겠습니다.
button.addEventListener('click', () => {
console.log('클릭됨');
});
button.click(); // 콘솔에 '클릭됨' 출력됨
////////////////////////////////////////////
button.addEventListener('click', (e) => {
if (e.isTrusted) {
console.log('진짜 클릭만 허용');
} else {
console.log('스크립트 클릭 무시');
}
});
button.click(); // '스크립트 클릭 무시'만 출력됨
위 두 코드는 모두 버튼이 클릭됐을 때 동작을 구현해주는 코드입니다. isTrusted 인 경우에만 예매하기 버튼이 눌리는 식으로 이루어지는데, 저 함수 내부에서 pointerdown, mousedown, mouseup 등의 이벤트들도 함께 감지 등 여러 추가 조건들이 붙습니다. 콘솔, 크롬 익스텐션에서 사용한 방법처럼 버튼을 눌렀을 때 다음 동작으로 넘어가게는 할 수 있지만, 이후에는 NetFunnel이 막고 있었죠.
그럼 어떻게 흉내 낼건데?
진짜 브라우저처럼 행동하는 자동화 도구로 Selenium과 Puppeteer이 있습니다. 브라우저 자동화 도구는 우리가 마우스로 클릭하고, 키보드로 입력하고, 페이지가 로드되길 기다리는 행동을 스크립트로 제어할 수 있습니다. 완벽하게 사용자를 흉내 낼 수 있는 거죠. NetFunnel이 뿌리는 키는 세션과 쿠키 기반입니다. 자동화도구는 브라우저 자체를 조작하기 때문에 이걸 그대로 통과할 수 있습니다.(줄을 앞지르는게 아니라, 줄의 앞부분에 설 수 있게 도와준다라는 뜻입니다.) 또한 예매 사이트 중 일부는 자동화 탐지도 걸려있지만, 우회 설정으로 피할 수도 있습니다.
Selenium vs Puppeteer
먼저 언어입니다. Selenium은 Python, Puppeteer은 JavaScript, TypeScript로 동작합니다. 크롬, 엣지, 사파리 등 다양한 브라우저를 지원하는 셀리니움과 달리 퍼피티어는 크롬(크로미움) 전용입니다.
퍼피티어는 퍼펫(puppet)을 다루는 사람 이라는 이름답게, 브라우저를 정교하게 조정할 수 있습니다. 비동기 처리 방식이 기본이라 초보자에게는 진입 장벽이 있을 수 있지만, 브라우저 제어 속도가 빠르고, puppeteer-extra-plugin-stealth와 같은 스텔스 플러그인을 통해 자동화 탐지 우회가 쉬워 예매 자동화 같은 실전 작업에 특히 강점을 보입니다.반면, 셀레니움은 구조가 비교적 직관적이고 동기 방식으로 동작하여, 로직을 순차적으로 따라가기에 훨씬 쉽습니다. 예매 외에도 단순한 웹 크롤링이나 폼 자동화처럼 복잡하지 않은 작업에는 셀레니움이 오히려 더 간편할 수 있습니다.(셀레니움의 유래는 수은(Mercury)를 해독하는 약으로 지었는데, 초기의 자동화 툴인 Mercury QTP라는 유료 툴을 디스하면서 경쟁 툴을 해독하는 오픈소스 자동화 도구라는 의미로 셀레니움이라는 이름이 붙었습니다.)
결국 두 도구 모두 브라우저 자동화를 위한 강력한 도구이며, 어떤 작업을 하느냐에 따라 선택이 달라집니다. 빠른 속도와 탐지 우회가 중요한 상황이라면 퍼피티어가 유리하고, 쉬운 사용성과 다양한 브라우저 지원이 필요하다면 셀레니움이 더 적합합니다. 맥만 사용하시는 분들은 셀레니움이 강제되겠지만, 본인의 목적과 익숙한 언어를 기준으로 선택하시면 됩니다. 한번도 개발을 해본 적 없으신 분들이라면, 셀레니움을 추천드립니다.
코드는 줘야지
이번 시간은 퍼피티어를 사용한 코드로 마무리하겠습니다. 자세한 내용을 다루기에는 퍼피티어와 셀레니움 필수 준비 리스트(Node.js, VS Code, Python 등)가 존재하기 때문에 글이 너무 길어질 것 같습니다. 내가 아는 파이썬은 스타크래프트 파이썬 밖에 없으신 분들도 따라하실 수 있는 퍼피티어 & 셀레니움 단계별 설치부터 실행까지의 과정은 다음 글에서 뵙도록 하겠습니다. 다시 한번 실제 예매 과정에서 이를 악용하거나 무단으로 활용하는 것은 서비스 약관 위반이 될 수 있으며, 법적 책임이 따를 수 있습니다.
[직링 자동화 도구] 퍼피티어를 이용해 콘서트 예매하기
지난 글에서는 실제 사용자의 동작을 흉내 내는 방식으로 콘서트 예매를 시도했습니다. 콘솔 창에서 HTML 요소를 확인한 후, 그 요소를 클릭하는 방식으로 진행을 했었지만, 예매하기 버튼이 콜
gnaaak.tistory.com
// 1. puppeteer, fs 모듈 불러오기
const puppeteer = require("puppeteer");
const fs = require("fs");
(async () => {
// 2. 브라우저 실행
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null,
args: ["--start-maximized"],
});
const page = await browser.newPage();
// 3. 새 탭 열기 & 쿠키 로딩
const cookies = JSON.parse(fs.readFileSync("cookies.json", "utf8"));
await page.setCookie(...cookies);
// 4. 티켓 예매 페이지로 이동
await page.goto(
"https://ticket.sapmle_url.com/concert/index.htm?some_id=******",
{
waitUntil: "networkidle2",
}
);
// 5. 팝업 닫기 시도
try {
await page.waitForSelector(".some_kind_of_notice", {
visible: true,
timeout: 5000,
});
await page.click(".close_some_kind_of_notice");
console.log("예매 안내 팝업 닫기 완료");
} catch (err) {
console.log("예매 안내 팝업 없음");
}
// 6. 날짜 선택
try {
await page.waitForSelector(".select_date button", {
timeout: 5000,
});
await page.click(".select_date button");
console.log("날짜 클릭 완료");
} catch (err) {
console.error("날짜 클릭 실패", err);
await browser.close();
return;
}
// 7. 시간 클릭
try {
await page.waitForSelector(".time button", { timeout: 5000 });
await page.click(".time button");
console.log("시간 클릭 완료");
} catch (err) {
console.error("시간 클릭 실패", err);
await browser.close();
return;
}
// 8. 예매 버튼 클릭
try {
await page.waitForSelector("buy_ticket_btn", { timeout: 5000 });
await page.click(".buy_ticket_btn");
console.log("예매 버튼 클릭 완료");
} catch (err) {
console.error(".예매 버튼 클릭 실패", err);
}
})();
'자유로운 개발일지 > 실험일지' 카테고리의 다른 글
[직링 자동화 프로그램] 퍼피티어, 일렉트론을 이용한 콘서트 예매 프로그램 (2) | 2025.05.26 |
---|---|
[직링 자동화 도구] 셀레니움을 이용해 콘서트 예매하기 (1) | 2025.05.24 |
[직링 자동화 도구] 퍼피티어를 이용해 콘서트 예매하기 (1) | 2025.05.23 |
[NetFunnel 우회] 직링 구하기 (2) | 2025.05.21 |
[크롬 익스텐션] 직링 구하기 (5) | 2025.05.17 |