728x90
728x90

 

프로젝트 명 : 빅데이터 기반 모의 야구경기 시뮬레이터

 

목표 1. 선수명단 스크래핑하기

 


 

 

1차 시도

프로그램은 영어로 제공될것이기에 영어 이름을 스크래핑해야했다.

 

http://eng.koreabaseball.com/Teams/PlayerSearch.aspx

 

KBO

 

eng.koreabaseball.com

 

정말 좋은 사이트를 찾았다.

각 구단별 선수들이 모두 나와있었고 영어 기반이다..

 

바로 코드를 짜봤다.

 

import requests
from bs4 import BeautifulSoup

# 팀 목록
teams = {
    '두산': '1',
    'KIA': '2',
    'KT': '3',
    'LG': '4',
    'NC': '5',
    '롯데': '6',
    '삼성': '7',
    'SSG': '8',
    '키움': '9',
    '한화': '10'
}

# 선수 정보를 저장할 리스트
player_list = []

# 각 팀별로 스크래핑 수행
for team_name, team_id in teams.items():
    url = f'http://eng.koreabaseball.com/Teams/PlayerSearch.aspx?pcode={team_id}'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    # 각 포지션별 탭에서 선수 정보 스크래핑
    positions = ['Pitcher', 'Catcher', 'Infielder', 'Outfielder']
    for position in positions:
        tab_id = soup.find('a', text=position)['href'].split('#')[1]
        tab_content = soup.find('div', {'id': tab_id})
        
        # 선수 정보 스크래핑
        players = tab_content.find_all('tr')[1:]
        for player in players:
            data = player.find_all('td')
            name = data[1].text.strip()
            info = data[2].text.strip()
            
            # 선수 정보를 딕셔너리로 저장 후 리스트에 추가
            player_info = {
                'Team': team_name,
                'Name': name,
                'Info': info
            }
            player_list.append(player_info)

# 결과 출력
for player in player_list:
    print(f"팀: {player['Team']}, 이름: {player['Name']}, 정보: {player['Info']}")

 

엑셀에 저장하는 기능까지는 구현하지 않았다

첫번째 목표는 출력해내기

 

이런.

이 코드는 soup.select_one() 함수를 사용하여 CSS 선택자를 이용하여 각 탭에 대한 링크를 찾게하고, 이를 통해 정확한 요소를 찾을 수 있으며, 오류가 발생하지 않도록 수정해보았다.

 

import requests
from bs4 import BeautifulSoup

# 팀 목록
teams = {
    '두산': '1',
    'KIA': '2',
    'KT': '3',
    'LG': '4',
    'NC': '5',
    '롯데': '6',
    '삼성': '7',
    'SSG': '8',
    '키움': '9',
    '한화': '10'
}

# 선수 정보를 저장할 리스트
player_list = []

# 각 팀별로 스크래핑 수행
for team_name, team_id in teams.items():
    url = f'http://eng.koreabaseball.com/Teams/PlayerSearch.aspx?pcode={team_id}'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    # 각 포지션별 탭에서 선수 정보 스크래핑
    positions = ['Pitcher', 'Catcher', 'Infielder', 'Outfielder']
    for position in positions:
        tab_link = soup.select_one(f'a[href*="#{position}"]')
        if tab_link:
            tab_id = tab_link['href'].split('#')[1]
            tab_content = soup.find('div', {'id': tab_id})
            
            # 선수 정보 스크래핑
            players = tab_content.find_all('tr')[1:]
            for player in players:
                data = player.find_all('td')
                name = data[1].text.strip()
                info = data[2].text.strip()
                
                # 선수 정보를 딕셔너리로 저장 후 리스트에 추가
                player_info = {
                    'Team': team_name,
                    'Name': name,
                    'Info': info
                }
                player_list.append(player_info)

# 결과 출력
for player in player_list:
    print(f"팀: {player['Team']}, 이름: {player['Name']}, 정보: {player['Info']}")

 

 

출력이 되지 않았다... 오류는 안 뜨는데;...

 

 

고군분투 끝에 해냈다

import requests
from bs4 import BeautifulSoup

# 웹 페이지 URL
url = "http://eng.koreabaseball.com/Teams/PlayerSearch.aspx"

# 선수 이름
player_name = "BAEK Seung Geon"

# GET 요청으로 HTML 가져오기
response = requests.get(url)
html = response.text

# BeautifulSoup을 사용하여 HTML 파싱
soup = BeautifulSoup(html, "html.parser")

# 선수 이름에 해당하는 요소 찾기
player_element = soup.find("a", text=player_name)

# 선수 정보가 없으면 종료
if player_element is None:
    print("선수를 찾을 수 없습니다.")
    exit(0)

# 선수 정보가 있는 table row 찾기
player_row = player_element.find_parent("tr")

# 선수 정보 추출
player_info = {}
for td in player_row.find_all("td"):
    # 각 td 요소의 title 속성을 가져와서 선수 정보에 추가
    title = td.get("title")
    if title:
        player_info[title] = td.text.strip()

# 가져온 선수 정보 출력
print("선수 이름:", player_name)
for key, value in player_info.items():
    print(key + ":", value)

 

백성준의 정보를 출력해냈다

 

선수 이름: BAEK Seung Geon
no.: 59
position: Pitcher
born: 2000-10-29
ht, wt: 183cm, 85kg

 

이제는 리스트의 모든 선수들을 출력할 차례

import requests
from bs4 import BeautifulSoup

# 웹 페이지 URL
url = "http://eng.koreabaseball.com/Teams/PlayerSearch.aspx"

# GET 요청으로 HTML 가져오기
response = requests.get(url)
html = response.text

# BeautifulSoup을 사용하여 HTML 파싱
soup = BeautifulSoup(html, "html.parser")

# 모든 선수 요소를 찾음
player_elements = soup.select('th[title="player"]')

# 모든 선수에 대한 정보를 저장할 리스트
all_players_info = []

for player_element in player_elements:
    player_name = player_element.text.strip()

    # 선수 정보가 있는 table row 찾기
    player_row = player_element.find_parent("tr")

    # 선수 정보 추출
    player_info = {'name': player_name}
    for td in player_row.find_all("td"):
        # 각 td 요소의 title 속성을 가져와서 선수 정보에 추가
        title = td.get("title")
        if title:
            player_info[title] = td.text.strip()

    # 선수 정보를 리스트에 추가
    all_players_info.append(player_info)

# 가져온 모든 선수의 정보 출력
for player_info in all_players_info:
    print("선수 이름:", player_info.pop('name'))
    for key, value in player_info.items():
        print(key + ":", value)
    print()  # 각 선수 정보 사이에 공백 라인을 출력

코드를 조금 만져서 성공했다

선수 이름: BAEK Seung Geon
no.: 59
position: Pitcher
born: 2000-10-29
ht, wt: 183cm, 85kg

선수 이름: CHO Sung Hun
no.: 43
position: Pitcher
born: 1999-03-22
ht, wt: 188cm, 85kg

선수 이름: CHOI Min Jun
no.: 67
position: Pitcher
born: 1999-06-11
ht, wt: 178cm, 83kg

선수 이름: CHUNG Dong Yoon
no.: 62
position: Pitcher
born: 1997-10-22
ht, wt: 193cm, 103kg

선수 이름: ELIAS Roenis
no.: 25
position: Pitcher
born: 1988-08-01
ht, wt: 185cm, 92kg

선수 이름: HAN Doo Sol
no.: 34
position: Pitcher
born: 1997-01-15
ht, wt: 177cm, 86kg

선수 이름: IM Jun Seob
no.: 48
position: Pitcher
born: 1989-07-16
ht, wt: 181cm, 88kg

선수 이름: JEON Young Jun
no.: 
position: Pitcher
born: 2002-04-16
ht, wt: 192cm, 110kg

선수 이름: JUNG Sung Gon
no.: 1
position: Pitcher
born: 1996-07-10
ht, wt: 181cm, 80kg

선수 이름: KIM Do Hyun
no.: 68
position: Pitcher
born: 2003-05-24
ht, wt: 179cm, 89kg

선수 이름: KIM Joo On
no.: 11
position: Pitcher
born: 1996-12-08
ht, wt: 187cm, 89kg

선수 이름: KIM Ju Han
no.: 21
position: Pitcher
born: 1993-02-03
ht, wt: 184cm, 93kg

선수 이름: KIM Kwang Hyun
no.: 29
position: Pitcher
born: 1988-07-22
ht, wt: 188cm, 88kg

선수 이름: KIM Tae Hoon
no.: 51
position: Pitcher
born: 1990-05-19
ht, wt: 176cm, 88kg

선수 이름: KO Hyo Jun
no.: 15
position: Pitcher
born: 1983-02-08
ht, wt: 179cm, 81kg

선수 이름: LEE Geun Wook
no.: 16
position: Pitcher
born: 1995-02-13
ht, wt: 182cm, 85kg

선수 이름: LEE Ki Soon
no.: 39
position: Pitcher
born: 2003-05-14
ht, wt: 174cm, 74kg

선수 이름: LEE Ro Un
no.: 92
position: Pitcher
born: 2004-09-11
ht, wt: 185cm, 105kg

선수 이름: LEE Won Joon
no.: 66
position: Pitcher
born: 1998-07-02
ht, wt: 190cm, 98kg

선수 이름: MCCARTY Kirk
no.: 33
position: Pitcher
born: 1995-10-12
ht, wt: 173cm, 83kg

선수 이름: MOON Seung Won
no.: 42
position: Pitcher
born: 1989-11-28
ht, wt: 180cm, 88kg

선수 이름: NOH Kyung Eun
no.: 38
position: Pitcher
born: 1984-03-11
ht, wt: 187cm, 100kg

선수 이름: OH Won Seok
no.: 47
position: Pitcher
born: 2001-04-23
ht, wt: 182cm, 80kg

선수 이름: PARK Jong Hun
no.: 50
position: Pitcher
born: 1991-08-13
ht, wt: 186cm, 90kg

선수 이름: PARK Min Ho
no.: 41
position: Pitcher
born: 1992-02-25
ht, wt: 185cm, 95kg

선수 이름: PARK Sang Hoo
no.: 64
position: Pitcher
born: 2003-08-05
ht, wt: 187cm, 87kg

선수 이름: PARK Si Hoo
no.: 46
position: Pitcher
born: 2001-05-10
ht, wt: 182cm, 88kg

선수 이름: ROMERO Enny
no.: 
position: Pitcher
born: 1991-01-24
ht, wt: 190cm, 105kg

선수 이름: SEO Dong Min
no.: 18
position: Pitcher
born: 1994-03-07
ht, wt: 186cm, 90kg

선수 이름: SEO Jin Yong
no.: 22
position: Pitcher
born: 1992-10-02
ht, wt: 184cm, 88kg

선수 이름: SHIN Heon Min
no.: 49
position: Pitcher
born: 2002-07-19
ht, wt: 187cm, 88kg

선수 이름: SONG Young Jin
no.: 98
position: Pitcher
born: 2004-05-28
ht, wt: 185cm, 90kg

선수 이름: YUN Tae Hyeon
no.: 30
position: Pitcher
born: 2003-10-10
ht, wt: 189cm, 93kg

이제 얘를 엑셀로 저장해보려고 한다

 

 

우리 팀은 아니지만 쓱의 모든 투수들의 정보를 출력해냈다

728x90
300x250

728x90
728x90

 

DNS(Domain Name System) : 인터넷에서 사용되는 주소체계

-사용자가 입력한 도메인 이름 (www.insidepixce.com)을 해당 도메인 이름과 연결된 IP주소로 변환하여 인터넷에서 데이터를 전송하는 데 사용됨

 

example

www.insidepixce.com 입력시 - 도메인 이름을 IP주소로 변환, 사용자가 요청한 웹 페이지의 데이터를 해당 IP 주소로 전송

서버가 전 세꼐에 구축되어 있으며, 사용자는 이러한 서버를 통해 인터넷에서 데이터를 전송할 수 있음

해커가 DNS 정보를 탈취하면 사용자의 개인 정보가 유출될 수 있음

 

DNS 정보 탈취하는 방법들

1. DNS 스푸핑 : 해커가 DNS 서버를 위조해 사용자가 입력한 도메인과는 다른 IP주소 제공

- 이를 통해 사용자의 데이터를 가로채거나 변조할 수 있음

 

ㄱ. DNS 쿼리 가로채기: 해커는 사용자가 입력한 DNS 쿼리를 가로채고, DNS 서버를 위조하여 사용자에게 임의의 IP 주소를 제공

ㄴ. DNS 서버 위장: 해커는 DNS 서버를 위조하여 사용자에게 임의의 IP 주소를 제

ㄷ. ARP 캐시 포이즈닝: ARP(Address Resolution Protocol) 캐시 포이즈닝은 해커가 사용자의 ARP 테이블을 위조하여 해커가 소유한 DNS 서버를 사용하도록 유도하는 것입니다.

 

2. DNS 캐싱 중독 

해커가 중간자 공격을 수행하여 DNS 정보를 변조하는 것

해커는 DNS 정보를 수정하여 사용자가 입력한 도메인 이름과 일치하지 않는 IP 주소를 제공한다. 이를 통해 해커는 사용자의 데이터를 가로채거나 변조할 수 있는 것이다 

 

 

  • DNS 스푸핑과 DNS 캐싱 중독의 차이

DNS 캐싱 중독과 DNS 스푸핑은 둘 다 DNS(Domain Name System) 정보를 조작하는 공격이지만, 조작 방법과 목적이 다르다

 

DNS 스푸핑

해커가 dns 서버를 위조하여 사용자가 입력한 도메인 이름과 일치하지 않는 IP 주소 제공하는 것.

대개 중간자 공격 (Man-in-the-middle Attack)과 함께 사용되어 인증서나 로그인 정보를 탈취하는 등의 악의적인 목적으로 이루어짐

 

DNS 캐싱 중독

dns 정보 조작함- dns 캐시 서버에 잘못된 정보 저장

이를 통해 사용자의 dns 쿼리를 위조된 ip주소로 전달함

DoS(Denial of Service) 공격에 사용

DNS 스푸핑은 DNS 쿼리를 해킹하여 실시간으로 DNS 정보를 조작하는 것이고, DNS 캐싱 중독은 DNS 정보를 조작하여 DNS 캐시 서버에 저장하는 것

 

 

DNS 유출 예방법

  1. DNS over Tor(DOT) 사용: DNS over Tor(DOT)는 Tor 네트워크 내에서 DNS 요청과 응답을 암호화하여 유출을 방지하는 기술. 토르 브라우저 설정에서 DOT을 사용하도록 설정할 수 있다
  2. Trusted Recursive Resolver(TRR) 사용: Trusted Recursive Resolver(TRR)은 DNS 요청과 응답을 암호화하여 유출을 방지하는 기술. 토르 브라우저 설정에서 TRR을 사용하도록 설정할 수 있다.
  3. DNSSEC(Domain Name System Security Extensions) 사용: DNSSEC은 DNS 데이터의 무결성을 검증하여 DNS 쿼리의 안정성을 향상시키는 기술. 토르 브라우저에서 DNSSEC을 사용하도록 설정할 수 있다.
  4. VPN 사용: VPN(Virtual Private Network)은 인터넷 연결을 암호화하여 개인 정보 유출을 방지하는 기술. 토르 브라우저에서 VPN을 사용하여 보안성을 강화할 수 있다.

 

 

728x90
300x250
728x90
728x90

다크웹이란 트래픽 추적과 네트워크 감시를 피하기 위한 정보통신 보호를 목적으로 설계되었다. 

대표적으로 tor 브라우저를 사용하게 되는데, 이는 그리 어렵지 않게 설치가 가능하기에 약간의 컴퓨터 지식만 있으면 다크웹에 접근할 수 있게 된다. 

 

이는 '추적이 불가능한 익명성'이라는 수식어 아래 많은 사람들의 범죄 수단이 되었다.

 

필자가 직접 조사를 위해 히든위키에 접속하여 확인한 결과 대다수의 사이트가 범죄와 관련된 사이트였다.

 

*히든위키란? 
-검색으로 접근할 수 없는 사이트들(딥웹)을 모아 둔 곳

(https://thehiddenwiki.org)

 

 

많은 사람들이 '딥웹'이라고 하면 다 토어로 접속해야 하고, 불법적인 던전이 있을 거라 기대하는데

 

사실 딥웹은 우리가 검색 엔진에 검색하였을 때 검색되지 않는 모든 웹을 말한다.

예를 들어 카카오톡이나, 개인 메일함 등이 있겠다.

한 층 더 분류해보면 '다크웹'이라는 개념이 나오는데, 

 

이게 토르 브라우저로 접속하여 온갖 불법 거래가 이뤄지는 곳을 일컫는 말이다.

오해 없기를 ^^

 

 

다크웹 검거 사례 (FBI)

 

제일 유명한건 '실크로드' 사건이 아닌가 싶다. 

실크로드는 토어 네트워크를 사용하여 익명으로 운영되었고,  토어 네트워크는 아까 설명했다싶이 중개 서버(relay server)를 사용하여 사용자의 ip 주소를 숨기고 사용자의 데이터를 암호화하여 보관하엿다,

 

또, 실크로드에서는 비트코인을 사용하여 거래가 이루어졌다. 비트코인은 블록체인 기술을 사용하여 거래 내역을 안전하게 기록했으며, 거래가 익명으로 이루어진다. 그러므로 누가 어떻게 얼마를 구매했는지 추적이 어려워졌다.

 

(언젠가 내가 비트코인의 블록체인 기술에 대해 완벽하게 이해하게 된다면 이에 관해서도 포스팅하겠다)

 

실크로드 검거 시 사용된 기술은 탐지 기술 (양방향 탐지 | bi-directional detection) 이 사용되었다. 이 방식은 사용자가 인터넷을 이용할 때, 해당 사용자와 서버 간의 송수신 패턴을 분석하여 양쪽의 신호를 감시하는 방식이다.

- 양방향 탐지에 관한 게시물은 내일 작성해보려 한다

탐지 기술 뿐만이 아니라 경찰은 실크로드를 장기 추적했다.

경찰이 사이트 내부의 관리자로 위장하여, 깊숙히 침투해 수개월동안 추적하였다고 한다

 

다크웹 검거 사례 (한국)

 

강원지방경찰청은 2017년 대마를 유통시키며 비트코인을 받아 챙긴 판매자와 대마를 구매한 70여명을 검거하였고, 2018년 서울지방경찰청은 밀반입한 마약을 다크웹에서 판매한 판매자와 구매자 80여명을 검거했다. 또, 2017년 8월 울산지방 경찰청은 약 4조 8천억원 상당의 마권을 발행해 다크웹에서 도박 프로그램을 운영한 사람들을 검거하였다.

 

https://news.mt.co.kr/mtview.php?no=2022082516355618162 

 

다크웹은 안 걸리겠지? 안심한 마약 구매자들…경찰 '전담팀'이 검거 - 머니투데이

올 하반기 마약 판매자, 구매자 200명쯤 추가 검거 예상특정 소프트웨어로만 접속할 수 있는 다크웹에서 가상자산(코인)으로 대마를 산 구매자 166명이 경찰에 붙잡혔다. ...

news.mt.co.kr

 

토르 추적 방식

 

이는 응용 프로그램 수준에서의 추적과 네트워크 수준에서의 추적으로 나누어진다.

 

응용프로그램 수준에서의 추적은 네트워크 자체의 문제에서 답을 찾는 것이 아니다. 

네트워크 사용자가 본인의 ip 주소를 실수로 노출시키거나, 멀웨어에 감염되어 토르네트워클르 거치지 않고 특정서버에 접속하는 경우 등이다. 

 

 

네트워크 수준에서의 추적은 주로 노드를 여러개 장악하여 트래픽 , 모니터링 패킷의 패턴, 시간 차를 분석하여 실제 히든서비스를 추적하는 방식이다. 

 

기회가 된다면 네트워크 수준에서의 추적 또한 깊게 공부해보고 싶다

728x90
300x250
728x90
728x90

 

익명성을 보장하기 위한 무료 오픈소스 브라우저

토어 네트워크를 사용하여 인터넷 연결을 중계하고,

사용자의 IP 주소를 숨겨준다.

 

비슷한 게 많다고 들었는데 아마 토어가 제일 유명한 것 같다.

정확한 발음은 토어인데, 한국 사람들은 토르라고 많이 부르곤 한다.

 

양파 보니까 눈물 날 것 같아

 

토르 브라우저가 추적하기 어려운 이유에는 여러가지 토르의 동작 방식들이 있다.

 

1. 중개 서버

토어 네트워크는 중개 서버(relay server)를 사용한다. 사용자가 인터넷에 연결할 때, 사용자의 연결 정보를 받아서 해당 정보를 다른 중개 서버로 전달한다. 이렇게 중개 서버를 거쳐서 연결이 이루어지면, 사용자의 IP 주소는 감추어지게 된다

 

*자발적으로 중개 서버('출입 노드 (entry node)')를 운영하는 사용자들도 있다.

사용자들의 연결이 토어 네트워크로 들어오는 곳에 위치한다. 이 노드를 통해 중개 서버 네트워크에 접속해, 익명으로 활동한다

 

- 이때 다중 중개 서버 경로 즉 여러 개의 중개 서버를 사용하여 사용자의 연결 정보가 하나의 중개 서버에 집중되지 않고 여러개를 걸쳐 나눠져 전달되게 한다. 이로 인해 사용자의 정보를 추적하기가 어려워진다.

 

-중개 서버는 무작위이다.

말 그대로 랜덤 그 자체.

+추적이 더 어려워진다

 

2.데이터의 전송 과정에서 암호화

데이터가 전송되는 과정에서 암호화되어버리기에 중개 서버를 거쳐 전달되는 데이터가 혹시나 노출되더라도 사용자의 정보가 드러나지 않는다.

 

그 외에도 중개 서버 운영자 모드 , 쿠키, 히스토리 , 캐시 등을 자동 으로 삭제하는 '개인 정보 보호 모드'  등이 있다.

 

 

일반적으로 토르의 트래픽은 세가지의 노드를 거쳐간다 (입구노드, 중간노드, 출구노드)

노드를 지날 때 마다 각각 공개키로 암호화되며, 

이때 노드는 출발지 ip (자신에게 보낸 ip) , 목적지 ip (담에 보낼 ip) 만 알기에 보안성이 더 강화된다.

 

 

예를 들어

 

대한민국 부산에서 접속 - 캐나다 네트워크 경유 - 아르헨티나 경유 - 미국 경유 - 일본 경유 - 베트남 경유

 

이런식으로 하여서 결론적으로 나는 베트남에서 접속한것으로 확인되는 것이다.

 

참고로 필자가 조사하기 위해 토르 브라우저를 사용해본 결과 정말 속이 터지게 느리다. 

 

다음 포스팅에선 다크웹 자체에 대해서 더 알아보겠다.

 

 

728x90
300x250

+ Recent posts