2021년 3월 1일 월요일

[파이썬] 네이버 증권 사이트에서 특정 종목 주가 보기

파이썬을 이용하여 특정 웹사이트 페이지 내용을 가져올 수 있는 코드는 지난번에 포스팅을 했습니다.

보통의 웹사이트는 많은 내용들이 포함되어 있어 단순히 웹사이트 페이지 가져오기만으로는 필요한 내용을 보기가 힘듭니다.

그래서 이번에는 요즘 많은 관심을 가지고 있는 주식의 주가를 쉽게 볼 수 있는 코드를 만들어 보기로 했습니다.

실시간으로 볼려면 한국거래소 등에서 제공하는 API를 사용한다고 하지만, 실제로 일반 개인에게는 개방을 하지 않는거 같습니다.

그래서 누구나 쉽게 접근할 수 있는 네이버 증권 사이트를 이용하기로 했습니다. 아시다시피 일반 포털에서 제공하는 정보는 실시간으로 주가 정보를 제공하지는 않지만, 증권사 페이지에 로그인하지 않으면서 참고로 주가를 알아보는데는 지장이 없을거 같습니다.

아래는 실제 네이버 증권 사이트에서 "삼성전자" 종목명을 조회하면 나오는 화면입니다.



주가를 알아내려면 이 화면의 실제 페이지 내용이 필요한데, 브라우저의 "페이지 소스보기" 메뉴를 사용하면 됩니다.

페이지 내용을 보면 많은 태그를 포함하는 html 내용이 나오는데, 그중에서 종목명에 대한 주가 정보는 아래와 같이 찾을 수 있습니다.

<dl class="blind">
    <dt>종목 시세 정보</dt>
    <dd>2021년 02월 26일 16시 11분 기준 장마감</dd>
    <dd>종목명 삼성전자</dd>
    <dd>종목코드 005930 코스피</dd>
    <dd>현재가 82,500 전일대비 하락 2,800 마이너스 3.28 퍼센트</dd>
    <dd>전일가 85,300</dd>
    <dd>시가 82,800</dd>
    <dd>고가 83,400</dd>
    <dd>상한가 110,500</dd>
    <dd>저가 82,000</dd>
    <dd>하한가 59,800</dd>
    <dd>거래량 36,715,024</dd>
    <dd>거래대금 3,026,814백만</dd>
</dl>

우리가 필요한건 dl 태그내의 내용입니다.

그래서 아래와 같이 코드를 작성해보았습니다. 여기서 "005930"은 삼성전자 종목코드인데, 다른 종목을 조회하려면 그에 맞는 종목코드로 바꾸면 됩니다.

import requests
from bs4 import BeautifulSoup

url = "https://finance.naver.com/item/main.nhn?code=005930"   #삼성전자 종목코드를 포함하는 url

response = requests.get (url)

if response.status_code == 200:
    html = response.text
    soup = BeautifulSoup (html, 'html.parser')
    print (soup.dl.text)   #태그내의 텍스트를 추출하여 출력


이 코드를 실행시키면 아래와 같이 텍스트만 추출해서 깨끗하게 출력이 됩니다.

D:\MyPyWork>python stock1.py

종목 시세 정보
2021년 02월 26일 16시 11분 기준 장마감
종목명 삼성전자
종목코드 005930 코스피
현재가 82,500 전일대비 하락 2,800 마이너스 3.28 퍼센트
전일가 85,300
시가 82,800
고가 83,400
상한가 110,500
저가 82,000
하한가 59,800
거래량 36,715,024
거래대금 3,026,814백만

물론 여기서 좀더 가공하면 더 보기좋게 할 수도 있겠습니다.

2021년 2월 28일 일요일

파이썬에서 특정 인터넷 사이트 페이지 내용을 가져오는 방법 (웹크롤링)

 

파이썬은 여러가지 패키지들이 있어 개발자가 구현하기 원하는 기능들을 쉽게 구현해줄 수 있도록 해줍니다.

 

아래 소스는 특정 인터넷 사이트의 url의 페이지 내용을 가져올 수 있도록 해줍니다.

 

import requests

from bs4 import BeautifulSoup

 

# 가져오기 원하는 url 주소

url = "https://www.naver.com"

 

response = requests.get (url)

 

if response.status_code == 200:   # 에러가 발생되지 않으면

    html = response.text

    soup = BeautifulSoup (html, 'html.parser')

    print (soup)

 

위에서 “requests.get”이나 “BeuatifulSoup”requests 패키지와 beuatifulsoup4 패키지에서 지원되는 함수로서 파이썬에 설치가 되어 있어야 사용할 수 있는데, 만약 설치가 되어 있지 않다면

 

pip install requests

pip install bueatifulsoup4

 

위의 명령을 명령 프롬프트 창에서 실행시키면 설치가 됩니다.

 

위의 코드를 실행시키면 Naver 홈페이지의 내용이 출력이 됩니다.

 

아시다시피 Naver 홈페이지 내용은 엄청난 양의 html 페이지로 일일이 보여드릴 수가 없네요.

 

beuatifulsoup4 패키지는 다양한 함수를 이용해서 가져온 html 페이지 내용을 처리할 수 있도록 해줍니다.

 

"print (soup)" 대신 "print (soup.title)"을 실행시키면 가져온 페이지의 title 부분만 추출해서 보여줄 수 있습니다.

 

D:\MyPyWork\sample1>python test1.py

<title>NAVER</title>

 

"print (soup)" 대신 "print (soup.title.string)"을 실행시키면 html title 태그를 뺀 내용만 보여줄 수 있습니다.

 

D:\MyPyWork\sample1>python test1.py

NAVER

 

"print (soup)" 대신 "print (soup.p)"을 실행시키면 html p 태그 부분만 추출하여 보여줄 수 있습니다.

 

D:\MyPyWork\sample1>python test1.py

<p class="dsc">선거 후보자에 대해 자동완성을 제공하지 않습니다.

<span class="dsc_inner">기간 : 4 2 0 ~ 4 15 18시까지</span>

<a class="link" href="#">자세히보기</a>

</p>

 

현재 보여준 것은 BeuatifulSoup 패키지로 할 수 있는 일부분만 보여준 것입니다.

2021년 2월 27일 토요일

파이썬에서 원하는 패키지를 설치하는 방법

 파이썬을 설치했을때 기본 패키지들은 같이 설치가 됩니다.

 

그러나 파이썬으로 원하는 기능을 위해 프로그래밍을 하다가 필요한 패키지가 설치되어 있지 않을 때가 있습니다.

 

이럴 경우 그 패키지를 설치해야 하는데, 그때 pip 명령을 명령 프롬프트 창에서 사용할 수 있습니다.

 

pip 명령은 파이썬 패키지 색인에서 최신 버전의 모듈과 그 의존성에 따라 설치됩니다.

 

아래는 하나의 예로써 BeuatifulSoup이라는 패키지를 설치하는 예입니다.

 

D:\MyPyWork>pip install beautifulsoup4

Collecting beautifulsoup4

  Using cached beautifulsoup4-4.9.3-py3-none-any.whl (115 kB)

Requirement already satisfied: soupsieve>1.2 in c:\users\user\appdata\local\programs\python\python38-32\lib\site-packages (from beautifulsoup4) (2.1)

Installing collected packages: beautifulsoup4

Successfully installed beautifulsoup4-4.9.3

 

정확한 버전이나 최소 버전을 명령 줄에서 직접 지정할 수도 있습니다. >, < 와 같은 비교 연산자나 셸에서 해석되는 다른 특수 문자를 사용할 때는, 패키지 이름과 버전을 큰따옴표로 묶어야 합니다. 여기서는

pip install PackageA==3.2.1    # 특정한 버전

pip install "PackageA>=3.2.1"  # 최소한의 버전

 

물론 설치한 패키지를 설치해제할 수도 있습니다. 아래는 위에 설치한 BeuatifulSoup이라는 패키지를 설치해제하는 예입니다.

 

D:\MyPyWork>pip uninstall beautifulsoup4

Found existing installation: beautifulsoup4 4.9.3

Uninstalling beautifulsoup4-4.9.3:

  Would remove:

    c:\users\user\appdata\local\programs\python\python38-32\lib\site-packages\beautifulsoup4-4.9.3.dist-info\*

    c:\users\user\appdata\local\programs\python\python38-32\lib\site-packages\bs4\*

Proceed (y/n)? y

  Successfully uninstalled beautifulsoup4-4.9.3

 

일반적으로, 적절한 모듈이 이미 설치되어 있으면, 다시 설치하려고 해도 아무런 효과가 없습니다. 기존 모듈을 업그레이드하려면 명시적으로 요청해야 합니다.

 

pip install --upgrade PackageA

 

pip 명령자체도 버전업이 필요할 수도 있는데 아래와 같이 메세지가 뜨는 경우가 생겼습니다.

 

WARNING: You are using pip version 19.2.3, however version 21.0.1 is available.

You should consider upgrading via the 'python -m pip install --upgrade pip' command.

 

그래서 메세지에서 알려준대로 pip 자체를 업그레이드해봤습니다.

 

D:\MyPyWork>pip install --upgrade pip

Collecting pip

  Downloading https://files.pythonhosted.org/packages/fe/ef/60d7ba03b5c442309ef42e7d69959f73aacccd0d86008362a681c4698e83/pip-21.0.1-py3-none-any.whl (1.5MB)

     |████████████████████████████████| 1.5MB 1.7MB/s

Installing collected packages: pip

  Found existing installation: pip 19.2.3

    Uninstalling pip-19.2.3:

      Successfully uninstalled pip-19.2.3

Successfully installed pip-21.0.1

 

이전 pip 19.2.3에서 21.0.1로 업그레이드가 되었네요.

2020년 7월 20일 월요일

파이썬의 특이한 튜플 (tuple) 데이타형

파이썬만의 특이한 데이타형이 있는데 바로 튜플(tuple)이라는 것이 있습니다.

형태를 보면 아주 리스트형과 비슷합니다. 하지만 몇가지 면에서는 조금 다른 재미있는 데이타형입니다.

리스트는 []를 사용하여 정의하는데요. 반면 튜플은 ()를 사용하여 정의합니다.

그리고 또다른 점은 리스트는 그 멤버들의 값을 변경할 수가 있는데, 튜플은 한번 정의하면, 그 멤버의 겂을 변경할 수가 없습니다.

튜플을 정의하는 방법은 아래 소스와 같습니다.

a1 = ()
print ("비어있는 tuple - tuple a1 ", a1)

a2 = (1,)
print ("원소가 하나만 있는 tuple - tuple a2 ", a2)

a3 = (1, 5, 3)
print ("원소가 여러개인 tuple - tuple a3 ", a3)

a4 = 1, 3, 9
print ("원소가 여러개인 tuple (괄호 없이 정의) - tuple a4 ", a4)

a5 = ('a', 'b', ('a', 'b'))
print ("원소가 문자이면서 여러개인 tuple - tuple a5 ", a5)

그리고 이 소스의 실행 결과는 아래와 같습니다.

비어있는 tuple - tuple a1  ()
원소가 하나만 있는 tuple - tuple a2  (1,)
원소가 여러개인 tuple - tuple a3  (1, 5, 3)
원소가 여러개인 tuple (괄호 없이 정의) - tuple a4  (1, 3, 9)
원소가 문자이면서 여러개인 tuple - tuple a5  ('a', 'b', ('a', 'b'))

다른 부분은 거의 리스트형과 비슷하지만 4번째 부분이 아주 특이합니다. 괄호없이 그냥 원소들을 나열하기만 해도 듀플로 정의된다는게 신기합니다.

2020년 7월 16일 목요일

Brute Force Attack

많은 악성코드의 유형과는 달리 Brute Force Attack은 웹사이트의 취약점에 의존하지 않는 공격입니다. 대신 이 공격은 취약하거나 추출 가능한 자격 증명을 가진 사용자를 목표로 합니다. Brute Force Attack은 단순하면서도 많은 표적을 겨냥할 수 있습니다.

Brute Force Attack은 대상에 대해 많은 양의 조합을 시도하면서 시작됩니다. 이러한 공격은 종종 하나의 암호가 유효하기를 희망하면서 계정 암호를 여러번 시도합니다. 가능한 모든 조합을 시도하는 것과 비슷합니다.

암호만이 무차별 공격의 대상이 아닙니다. 링크와 디렉토리, 사용자 이름 및 이메일은 또다른 일반적인 대상입니다.

Brute Force Attack의 목적은 다른 사용자에게는 접근금지되어 있는 리소스에 액세스하는 것입니다. 이것은 관리 계정, 암호로 보호된 페이지일 수 있거나 단순히 주어진 웹사이트에서 유효한 전자 메일을 열람하기 위한 것일 수 있습니다.

유효한 계정에 액세스하면 전체 사이트가 손상될 수 있으며 이는 악의적인 행위자가 손상된 웹사이트 네트워크의 일부로 사용할 수 있습니다.

가장 일반적인 유형의 Brute Force Attack은 사전 공격 (Dictionary Attack)이며 일반적으로 관리 사용자 이름 및 암호를 사용하여 관리 계정에 액세스하여 자격 증명 목록을 포함합니다.

일반적인 사전 공격 (Dictionary Attack) "admin" "123456"과 같이 가장 일반적으로 사용되는 자격 증명으로 로그인을 시도합니다.

Brute Force Attack 시도를 식별하는데는 상식이 중요합니다. 기본적으로 누군가가 반복적으로 로그인에 실패한 것으로 보이는 경우 Brute Force Attack 시도일 가능성이 있습니다. 아래의 경우가 그런 경우입니다.

▶ 동일한 IP 주소가 여러번 로그인에 실패했습니다.
▶ 하나의 계정으로 로그인하려는 많은 다른 IP 주소가 실패했습니다.
▶ 단기간에 다양한 IP 주소에서 여러번 로그인에 실패했습니다.

Brute Force Attack은 봇넷에 사용자를 추가하여 DDoS 공격에 포함시킬 수 있는 방법도 있습니다. 다른 예로는 공격자가 웹 사이트를 손상시키기 위해 자격 증명을 무력화하는 방법이 있습니다.

웹사이트에서 관리 계정에 액세스하는 것은 심각한 취약점을 악용하는 것과 같습니다. 해커는 스팸을 추가하거나 맬웨어를 배포하거나 의심하지 않는 피해자를 피싱하는 등 액세스를 통해 이익을 얻으려고 시도합니다.

기본적으로 Brute Force Attack은 가능한 많은 조합을 시도하는 행위이지만 성공률을 높이기 위해 이 공격에는 여러가지 변형이 있습니다. 가장 일반적인 것은 다음과 같습니다.

▶ 간단한 무차별 대입 공격

일반적인 Brute Force Attack은 한번에 하나씩 가능한 모든 암호를 반복하는 것과 같은 다양한 방법을 사용할 수 있습니다. 다른 공격들도 성공률이 높은 시도 횟수에 제한이 없는 로컬 파일에서 일반적으로 사용됩니다.

Dictionary Attack

이 공격은 무작위로 들어가지 않고 단어와 일반 암호 목록을 사용하여 가능한 암호의 "사전"을 작성하고 반복합니다. 좋은 암호 목록을 사용하면 공격자의 성공률을 높이는데 도움이 될 수 있지만 이러한 공격에는 종종 가능성이 많은 대상에 대한 많은 공격 시도가 필요합니다.

Hybrid Brute Force Attack

하이브리드 공격은 사전 공격과 규칙적인 반복 패턴을 모두 사용합니다. 문자 그대로 모든 암호를 사용하는 대신 숫자를 추가하거나 대소 문자를 변경하는 등 사전의 단어를 약간 수정합니다.

Credential Stuffing

데이터 유출이 증가함에 따라 비밀번호 재사용은 비밀번호를 재사용하는 특정 계정을 손상시키는 쉬운 방법입니다.

Credential Stuffing 공격은 성공률이 낮으며 주로 데이터 유출에서 일반적으로 발견되는 사용자 이름 및 비밀번호 목록에 의존합니다. 해커는 이 목록을 사용하여 도난된 자격 증명으로 로그인을 시도하며, 데이터가 유출되었다고 생각될때 사용자 이름과 비밀번호를 업데이트해야 합니다.

Brute Force Attack에 대해서는 보안 취약점의 헛점을 노리는 것이 아니기 때문에 소프트웨어를 최신 상태로 유지하는 것만으로는 자신을 보호할 수 없습니다. 이러한 공격을 방지하는 일반적인 방법은 다음과 같습니다.

▶ 강력한 비밀번호 사용

Brute Force Attack는 취약한 비밀번호에 의존합니다. 강력한 암호를 위해서는 여러 사이트에 같은 암호를 사용하지 않아야 하며, 가능한한 긴 암호를 사용해야 합니다. 그러면서도 쉽게 유추가능한 암호는 피해야 합니다. 자신의 이름이나 거주 도시와 같은 정보가 암호를 기억하기 쉽게 만들 수 있지만 누군가가 사용자에 대한 정보를 얻거나 추측하기가 더 쉽습니다.

이러한 방식으로 암호를 설정한다면 Brute Force Attack은 암호를 추측할 수 없으므로 안전합니다.

암호찾기 질문에도 동일한 원칙이 적용됩니다. 암호는 강력하지만 암호찾기 질문이 약하면 공격자는 기존 암호를 추측하지 않고 바로 새로운 암호로 재설정하기가 쉽습니다.

▶ 인증 URL에 대한 액세스 제한

Brute Force Attack의 사전 조건은 자격 증명을 보내는 것입니다. 로그인 페이지 URL을 변경하면 ( : /wp-login.php에서 / mysite-login으로 이동) 대부분의 자동화된 대량 도구를 중지하기에 충분할 수 있습니다.

안타깝게도 이 제안은 링크가 추측 가능하거나 링크가 페이지에 표시되는 경우 고급 공격에는 적용되지 않습니다. 하지만 자동 공격을 방지하는 쉬운 방법입니다.

▶ 로그인 시도 제한

Brute Force Attack은 여러 개의 비밀번호와 계정을 시도합니다. 로그인 시도수를 제한함으로써 공격자는 여러가지 암호 시도를 할 수가 없습니다.

로그인 시도를 제한하는 일반적인 방법은 5번의 로그인 시도 실패후 IP 로그인이 일시적으로 금지되어 로그인 시도가 차단되는 것입니다.

▶ 보안 문자 사용

보안 문자는 봇 및 자동화된 도구가 웹사이트에서 로그인을 시도하기 전에 보안문자를 입력해야만 하게 하면 웹사이트에서 작업을 수행하지 못하게 하는 좋은 방법입니다. 보안문자는 사용자가 읽어 입혁해야 하기 때문에 로봇이 공격을 하기가 어렵게 만듭니다.

▶ 이중 인증 사용 (Two-Factor Authentication : 2FA)

2FA는 로그인 양식에 다른 보안 계층을 추가합니다. 적절한 자격 증명으로 로그인한 후에는 이메일 또는 인증 도구로 생성된 고유 코드와 같이 사용자만 액세스 할 수 있는 코드를 입력해야 합니다.

이 추가 계층은 자격 증명을 성공적으로 얻은 사람이 보조 인증없이는 계정에 액세스하지 못하게 합니다.

2020년 7월 15일 수요일

파이썬 continue와 break 사용법

파이썬에서도 C 언어의 continue break와 똑같은 키워드를 지원하는데요.

사용법은 C 언어와 동일합니다.

아래는 continue 사용에 대한 소스인데요. continue를 만나면 while loop의 마지막까지 모든 실행문을 건너뛰게 됩니다.

a = 0

while (a < 5):
    a = a + 1
    if (a == 4):
        continue
    print ("a : ", a)

아래는 위의 소스의 실행 결과인데요. a 4이면 아래의 print문을 건너뛰고 while문의 맨위로 가게 됩니다. 결국 a 4일때는 print 결과가 나오지 않게 됩니다.

a :  1
a :  2
a :  3
a :  5

아래는 break의 사용에 대한 소스인데요. continue와 달리 break while문을 빠져 나가게 합니다.

a = 0

while (a < 5):
    a = a + 1
    if (a == 4):
        break
    print ("a : ", a)

아래의 결과를 보면 a 4이면 바로 while문을 나가 종료하게 되고 a 3일때까지만 실행됩니다.

a :  1
a :  2
a :  3

2020년 7월 14일 화요일

화이트 박스 암호화 (White Box Cryptography)

암호화는 개방형 장치 ( : PC, 태블릿 또는 스마트폰)에서 실행되는 응용프로그램에 점점 더 많이 적용되고 있습니다. 공격자가 실행 플랫폼과 소프트웨어 구현 자체를 완벽하게 제어할 수 있을 가능성이 많기 때문에 이러한 시스템의 개방성은 소프트웨어가 공격에 매우 취약하게 됩니다. 이는 공격자가 응용프로그램의 이진 코드와 해당 메모리 페이지를 실행하는 동안 쉽게 분석할 수 있음을 의미합니다. 침입자는 IDA Pro, 디버거, 에뮬레이터 등과 같은 모든 종류의 공격 도구를 사용하여 시스템 호출을 가로채서 바이너리와 그 실행을 변조할 수 있습니다. 이러한 공격 컨텍스트는 화이트 박스 공격 컨텍스트라고 합니다.

화이트 박스 암호화가 해결해야 할 과제는 화이트 박스 공격을 받을 때에도 암호화 자산이 안전하게 유지되는 방식으로 소프트웨어에서 암호화 알고리즘을 구현하는 것입니다. 따라서 화이트 박스 암호화 (WBC)는 모든 소프트웨어 보호 전략에서 필수적인 기술입니다. 이 기술을 사용하면 암호화 키와 같은 기밀 정보의 일부를 공개하지 않고도 암호화 작업을 수행할 수 있습니다. 이것이 없으면 공격자는 바이너리 (메모리) 에서 비밀 키를 쉽게 얻거나 실행시 공개로 이어지는 정보를 가로챌 수 있습니다.

WBC는 주어진 암호를 강력한 표현으로 바꾸는 특수 목적 코드 생성기로 볼 수 있습니다. 비밀 키의 조작이 임의의 데이터 및 코드와 결합되어 임의의 데이터를 키 정보와 구별 할 수 없게 합니다.

아래 그림은 고정 키 구현의 경우 WBC에 대한 개념적 상위 레벨 개요를 보여줍니다. 이러한 구현에서, 키는 코드에 하드코딩될 것입니다. 화이트 박스 변환은 코드에 포함된 키를 추출하기 어려운 애플리케이션의 코드를 생성하는 것입니다.