개발 세션 - 명세 재설정 및 기존 코드 개보수

goldenGlow_21·2024년 12월 20일
0

특기사항

  • ElasticSearch 폐기 : 기간상 연동 어려움
  • 크롤러 일부 폐기 : 다크웹 개인 정보 데이터는 돌고 돌기 때문에 굳이 많은 웹 사이트를 얻을 필요가 없다…
  • Captcha 우회 추가 시도?

최종 서비스 형태 결정

Necessity(이 서비스를 고객이 사용할 이유 - 유인요소)

    • 다크웹은 그 특성 상 각 페이지가 접근하기 힘듬(url의 무규칙성)
    • 정보가 효용성을 지닌다고 판단된 source 몇 곳에서 새로이 올라오는 데이터들에 대해 정보를 수집하고, 이용자에게 알려주는 서비스를 제공한다면 일반인들도 tor66 등의 navigation 과정을 거치지 않고도 정보를 수집할 수 있게 됨
  • 최종 명세

    • 다크웹 포럼에서 다루는 IT 지식들은 surface web의 것보다 더 실전적임.
      • 따라서 이를 원하는 이용자들에게 수요가 반드시 존재함
    • 다양한 source를 탐색하고, 유출이 이루어진 출처를 정확히 파악할 수 있게 함
      • 정보가 유출된 개인이나 회사에서 문제의 원인을 짚고 싶을 떄 수요가 발생

Usage Step(이 서비스를 이용할 때의 사용 단계 - 고객이 겪는)

    • 서비스는 서버 상에서 동작. 정해진 시간에 스캔을 수행, 그 결과를 사용자에게 전송(알림)
    • 운영 중인 웹 페이지에 접근한다면 사용자는 IT 주제의 Forum 글들을 열람 가능
    • DB에 저장할 유출 데이터의 간략 정보를 열람 가능(RAW는 미제공)
  • 최종 명세

    • 정해진 시간에 탐지 정보에 대한 일람을 지정 매체로 전송
      • 카카오톡? 이메일? 디스코드?
    • 제공하는 웹 페이지에서 유출 정보와 IT 포럼 포스팅을 열람할 수 있도록 함

Convenience(이용자 중심의 편의성 조치 - UI가 좋다거나 웹 페이지가 적다…)

    • 카카오톡, 텔레그램, 디스코드, 이메일 등 접근성 좋은 매체로 크롤링 정보를 제공할 것
    • DB의 유출 데이터 목록이나 포럼의 정보를 열람하고 싶다면 웹 페이지에 접근해 Navbar 항목을 선택하는 것 만으로 원하는 정보에 쉽게 접근 가능
    • 사용자가 크롤링 과정에 개입할 필요 없음
  • 최종 명세

    • 카카오톡, 텔레그램, 디스코드, 이메일 등 접근성 좋은 매체로 정해진 시간에 크롤링 정보를 제공할 것
    • 크롤링을 사용자가 직접 할 필요 없음

Form(제공할 서비스의 형태 - 웹, CLI 등)

    • 웹 기반
    • 제공될 알림은 사용 매체에 따라 달라질 예정
  • 최종 명세


명세 확정

고객이 이 서비스를 사용할 유인요소

  • 다크웹 포럼에서 다루는 IT 지식들은 surface web의 것보다 더 실전적임.
    • 따라서 이를 원하는 이용자들에게 수요가 반드시 존재함
  • 다양한 source를 탐색하고, 유출이 이루어진 출처를 정확히 파악할 수 있게 함
    • 정보가 유출된 개인이나 회사에서 문제의 원인을 짚고 싶을 떄 수요가 발생

고객이 이 서비스를 이용할 때의 단계(체험)

  • 정해진 시간에 탐지 정보에 대한 일람을 지정 매체로 전송
    • 카카오톡? 이메일? 디스코드?
  • 제공하는 웹 페이지에서 유출 정보와 IT 포럼 포스팅을 열람할 수 있도록 함

사용자를 위한 편의성 조치

  • 카카오톡, 텔레그램, 디스코드, 이메일 등 접근성 좋은 매체로 정해진 시간에 크롤링 정보를 제공할 것
  • 크롤링을 사용자가 직접 할 필요 없음

제공할 서비스의 형태


일정 재정의

일차내용
12.13웹 페이지 프론트엔드 완성
12.14(토)크롤러 소수정예화
12.15(일)백엔드 중추 코드 작성 - main, db
12.16(월)알림 시스템 - 디스코드 / 이메일
12.17(화)문서화 / PPT / 기능 테스트
12.18(수)문서화 / PPT / 기능 테스트
12.19(목)문서화 / PPT / 제출 마감
12.20(금)발표

HTML 준비

HTML 세부 기능 구현

백 프론트 주고받을 데이터 항목

  • 크롤링한 데이터 (JSON)
    • 데이터의 형태
  • OSINT / DarkWeb 선택
    • 위의 옵션 선택 후: 크롤러 종류 지정

크롤러 개보수

Ctifeed

  • 얜 고칠 게 없는데

Island

  1. 각 카테고리는 수집할 json형태의 데이터 상에서 "type"으로 구분되니, 최종적으로 반환할 json 형태의 데이터를 만들 때, 구분해 반환해줄 필요 없음. 3개의 카테고리를 모두 크롤링해, 하나의 결과로서 반환해주길 바람.

  2. 각 카테고리의 url을 보면 맨 끝에 1이 붙어 있음. 이 숫자는 해당 페이지에서의 데이터 페이지 순서로, 숫자를 늘려가면 더 많은 데이터들이 나옴. 각 카테고리별로 1번부터 10번 페이지까지 크롤링해올 것.

  3. 각 카테고리의 url을 보면 맨 끝에 1이 붙어 있음. 이 숫자는 해당 페이지에서의 데이터 페이지 순서로, 숫자를 늘려가면 더 많은 데이터들이 나옴. 각 카테고리별로 1번부터 10번 페이지까지 크롤링해올 것.


Island 정보 수집

Accounts 카테고리

http://cislandpsv4xex2cy4t3vx4ogswq375fwnarmtfyarqek5ikxq57ioyd.onion/category/accounts/1

<div class="row g-0"><div class="col"><article itemscope="" itemtype="https://schema.org/Article"><a itemprop="url" class="island-card-link" data-island="x499k-usa-email-combolist" href="/x499k-usa-email-combolist"><div class="card-body"><h3 itemprop="headline" class="card-title"> x499k USA Email Combolist</h3><div class="island-attrs"><span itemprop="about" class="island-bold">Accounts</span><span class="me-2"></span><span itemprop="dateCreated" class="muted">May 04, 2024</span><span class="me-2"></span></div><p itemprop="text" class="card-text">Explore our extensive assortment of 499,000 USA email accounts!</p></div></a></article></div></div>

Combolists 카테고리

http://cislandpsv4xex2cy4t3vx4ogswq375fwnarmtfyarqek5ikxq57ioyd.onion/category/combolists/1

<div class="row g-0"><div class="col"><article itemscope="" itemtype="https://schema.org/Article"><a itemprop="url" class="island-card-link" data-island="24k-usa-combolist" href="/24k-usa-combolist"><div class="card-body"><h3 itemprop="headline" class="card-title"> 24K USA Combolist</h3><div class="island-attrs"><span itemprop="about" class="island-bold">Combolists</span><span class="me-2"></span><span itemprop="dateCreated" class="muted">Jul 26, 2023</span><span class="me-2"></span></div><p itemprop="text" class="card-text">Here we have a 24K USA combolist for you.</p></div></a></article></div></div>

Packs 카테고리

http://cislandpsv4xex2cy4t3vx4ogswq375fwnarmtfyarqek5ikxq57ioyd.onion/category/packs/1

<div class="row g-0"><div class="col"><article itemscope="" itemtype="https://schema.org/Article"><a itemprop="url" class="island-card-link" data-island="ultimate-skype-cracking-tools-pack" href="/ultimate-skype-cracking-tools-pack"><div class="card-body"><h3 itemprop="headline" class="card-title"><span class="card-featured">FEATURED</span> Ultimate Skype Cracking Tools Pack</h3><div class="island-attrs"><span itemprop="about" class="island-bold">Packs</span><span class="me-2"></span><span itemprop="dateCreated" class="muted">Dec 04, 2024</span><span class="me-2"></span><span class="island-bold">770 downloads</span></div><p itemprop="text" class="card-text">Download the Ultimate Skype Cracking Tools Pack – Resolve, Locate, and Exploit Skype Accounts with Ease.</p></div></a></article></div></div>

island_crawler.py 완성본

import json
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
from jsonschema import validate, ValidationError
import time

# ChromeDriver 경로 (프로젝트 폴더 내에 위치한 chromedriver.exe)
current_dir = os.path.dirname(os.path.abspath(__file__))
chromedriver_path = os.path.join(current_dir, "chromedriver.exe")

# TOR 프록시 설정
proxy_address = "127.0.0.1:9050"  # TOR SOCKS5 프록시 주소

# Selenium WebDriver 옵션 설정
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument(f"--proxy-server=socks5://{proxy_address}")  # TOR 프록시 사용

# WebDriver 초기화
service = Service(chromedriver_path)
driver = webdriver.Chrome(service=service, options=chrome_options)

# JSON Schema 정의
schema = {
    "type": "object",
    "properties": {
        "title": {"type": "string"},
        "url": {"type": "string"},
        "type": {"type": "string"},
        "dateCreated": {"type": "string"},
        "description": {"type": "string"}
    },
    "required": ["title", "url", "type", "dateCreated", "description"]
}

# 크롤링 대상 URL 카테고리 목록
categories = {
    "Accounts": "http://cislandpsv4xex2cy4t3vx4ogswq375fwnarmtfyarqek5ikxq57ioyd.onion/category/accounts/",
    "Combolists": "http://cislandpsv4xex2cy4t3vx4ogswq375fwnarmtfyarqek5ikxq57ioyd.onion/category/combolists/",
    "Packs": "http://cislandpsv4xex2cy4t3vx4ogswq375fwnarmtfyarqek5ikxq57ioyd.onion/category/packs/"
}

# 데이터 저장용 리스트
all_data = []

def crawl_category(category_name, base_url):
    for page_num in range(1, 11):  # 1번부터 10번 페이지까지
        try:
            url = f"{base_url}{page_num}"
            driver.get(url)
            time.sleep(5)  # 페이지 로딩 대기

            # BeautifulSoup으로 HTML 파싱
            soup = BeautifulSoup(driver.page_source, "html.parser")
            posts = soup.find_all("a", class_="island-card-link")

            for post in posts:
                try:
                    title = post.find("h3", itemprop="headline").text.strip()
                    post_url = "http://cislandpsv4xex2cy4t3vx4ogswq375fwnarmtfyarqek5ikxq57ioyd.onion" + post["href"]
                    post_type = category_name
                    post_date = post.find("span", itemprop="dateCreated").text.strip()
                    description = post.find("p", itemprop="text").text.strip()

                    # 데이터 저장
                    post_data = {
                        "title": title,
                        "url": post_url,
                        "type": post_type,
                        "dateCreated": post_date,
                        "description": description,
                    }

                    # JSON Schema 검증
                    try:
                        validate(instance=post_data, schema=schema)
                        all_data.append(post_data)
                        print(f"추출 완료: {title}")
                    except ValidationError as e:
                        print(f"데이터 검증 실패: {e.message}")

                except Exception as e:
                    print(f"게시물 처리 중 오류 발생: {e}")

        except Exception as e:
            print(f"페이지 크롤링 중 오류 발생 (카테고리: {category_name}, 페이지: {page_num}): {e}")

def crawl_island():
    try:
        for category_name, base_url in categories.items():
            crawl_category(category_name, base_url)

        # JSON 파일로 저장 (주석 처리)
        # with open("island_data.json", "w", encoding="utf-8") as f:
        #     json.dump(all_data, f, ensure_ascii=False, indent=4)
        # print("island_data.json 파일 저장 완료.")

        return all_data

    finally:
        driver.quit()

if __name__ == "__main__":
    result = crawl_island()
    print(result)
profile
안드로이드는 리눅스의 꿈을 꾸는가

0개의 댓글