파이썬3 웹 크롤링 HTTP error 403 발생시 해결방법

반응형

안녕하세요?

 

오늘은 그동안 잘 되던 웹크롤링에서 http error 403 이 발생하여 해결한 내용 기록하겠습니다.

 

urllib . error . HTTPError :   HTTP  Error  403 :  Forbidden

 

에러가 발생한 이유는 mod_security 또는 다른 비슷한 서버 시큐리티가 알려진 사용자 봇을 블록 시키기 때문이라고 합니다.

가이드에 따라,

브라우저 유저 에이전트를 시도해 보았습니다.

 

수정전>

from urllib.request import Request, urlopen

urlTicker = urllib.request.urlopen('https://api.bithumb.com/public/ticker/%s_KRW' % ticker) 
readTicker = urlTicker.read()
jsonTicker = json.loads(readTicker)

<수정후>

from urllib.request import Request, urlopen

urlTicker = 
Request('https://api.bithumb.com/public/ticker/%s_KRW' % ticker, headers={'User-Agent': 'Mozilla/5.0'})
readTicker = urlopen(urlTicker).read()
jsonTicker = json.loads(readTicker)

오~ 역시, 깔끔하게 해결이 되었습니다.

 

다음 블러그를 참조하여 작성하였습니다. 도움에 감사드립니다.

 

m.blog.naver.com/PostView.nhn?blogId=naturelove87&logNo=221908009605&proxyReferer=https:%2F%2Fwww.google.com%2F

 

파이썬3 웹 크롤링 HTTP error 403이 뜰 때 해결하는 방법

파이썬3에서 urllib.request를 사용할 때 HTTP Error 403이 뜰 때 해결하는 방법​다음과 같은 코드를...

blog.naver.com

https://stackoverflow.com/questions/16627227/http-error-403-in-python-3-web-scraping

 

HTTP error 403 in Python 3 Web Scraping

I was trying to scrap a website for practice, but I kept on getting the HTTP Error 403 (does it think I'm a bot)? Here is my code: #import requests import urllib.request from bs4 import Beautiful...

stackoverflow.com

 

반응형

댓글()

코인API 자동매매일지-2021.04.03

가상화폐|2021. 4. 3. 09:20
반응형

안녕하세요?

두번째 코인자동매매일지입니다.

요즘 코인거래량이 상당히 증가하면서, 비트코인이 연일 최고가를 경신하고 있습니다.

일부 코인은 하루 만에 가격이 두배가 되기도 하는것 같습니다.

하지만, 저의 프로그램은 이런 폭증과 무관하게 일정수익만을 내면서

천천히 금액이 증가되도록 거래가 조정되는 것 같습니다.

 

오늘은 어제 오후3시경 시점 기준보다 4.56%증가 된것 같습니다.

자동매매프로그램 화면
빗썸 자산현황 메뉴화면

 

반응형

댓글()

ufunc 'add' did not contain a loop with signature matching types (dtype('<U170'), dtype('<U170')) -> dtype('<U170')

반응형

안녕하세요?

 

이 에러 메세지 원인을 못찾아서 거의 한시간을 헤멨습니다.

혹시, 이 에러 원인을 찾는 분이 계시다면 도움되시길 바랍니다.

 

다른 분들은 어떤 부분에서 에러나는지 모르겠지만,

저는 하기 sqlCode Text 문장을 만들어서 

 

try: 

    sqlCode = "select date, low from '" + ticker + "' t1 where t1.date <= (select max(t2.date) from '" + ticker + "' t2

    where t2.date < ( select date(max(t3.date), '-1 day') from '" + ticker + "' t3) and t2.low < " + current_price + ")"

 

    chart_data_low = pd.read_sql(sqlCode, con, index_col=None) # 추가로 인덱스 칼럼이 생성되지 않도록 한다.

except Exception as e:
    self.logging.logger.debug("(%s) retrieve_db_chart_data_low Exception발생: %s" % (ticker, e))
    print("chart_intervals: %s" % chart_intervals)

 

이렇게 하는 과정에서 Exception Error가 발생했습니다.

 

sqlCode 문자열을 생성할때, 문자열들만의 문자열 합하기가 되도록 중간중간의 인자값을 잘 확인하시기 바랍니다.

 

그럼, 즐(거운)파(이썬) 하시길 바랍니다.

반응형

댓글()

python exe 파일 실행시 failed to execute script 오류 해결하기

가상화폐|2021. 3. 7. 10:36
반응형

일단, pyinstaller를 삭제하고 다시 설치해 보겠습니다.

pip uninstall pyinstaller

다시 설치하기

pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip

다시 auto-py-to-exe 를 실행합니다.

하지만. 동일한 오류가 발생합니다. pyinstaller 버젼이나 설치오류와는 아무 관련이 없었습니다.

다시.. 여기 사이트를 참조하여 다시 해 보겠습니다.

In PyInstaller, Why Won't NumPy.Random.Common Load as a Module?

 

import pandas as pd 앞부분에 붉은색 부분 추가합니다.

# 추가한 부분
import numpy.random.common 
import numpy.random.bounded_integers 
import
 numpy.random.entropy

import pandas as pd

다음과 같이 다시 pyinstaller를 실행해 봅니다.

pyinstaller --icon=test.ico --onefile --noconsole -F -n goldcoin.exe -c --clean main.py
-F: 한 개의 파일로 만들기. 용량은 당연히 조금더 커진다. (없을 시 dll 파일들과 분리되어 폴더로 생성됨)
-n: 이름짓기. 이름은 바로 오른쪽에 기입 (없을 시 소스파일명과 동일한 파일이 생성됨)
--noconsole: exe파일 실행시 콘솔창 띄우지 않기
--onefile: import 된 라이브러리를 따로 생성하지 않고 exe 파일 안에 다 넣고 싶은 경우
--icon=test.ico: 실행파일의 아이콘을 바꾸고 싶다면 추가


D:\PycharmProject\BithumAPI\dist 여기에 goldcoin.exe파일이 잘 만들어져 있네요.

하지만.. 실행시에 다음과 같은 오류가 또... 

 

GUI 라이브러리를 사용할 때는 pyinstaller 후 생성된 .spec 파일을 수정해야 된다고 하네요.

(1) .spec 파일에서 라이브러리를 추가하고, coll 부분을 수정

(2) pyinstaller .spec

(3) .exe 파일 실행

 

함 해 보죠.. 

m.blog.naver.com/PostView.nhn?blogId=qbxlvnf11&logNo=221791248065&proxyReferer=https:%2F%2Fwww.google.com%2F

 

상세내용은 여기를 참조하라고 하네요..

kivy.org/doc/stable/guide/packaging-windows.html

 

다음은 main.spec의 내용입니다.

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None



a = Analysis(['main.py'],
             pathex=['D:\\PycharmProject\\BithumAPI'],
             binaries=[],
             datas=[('./TA_Lib-0.4.19-cp37-cp37m-win32.whl', '.')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='goldcoin.exe',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=True )

 

이번에는 수정한 spec파일을 pyinstaller 실행합니다.

pyinstaller --icon=.\image\goldcoin_1.ico --onefile --noconsole -F -n goldcoin.exe -c --clean main.spec

여전히 talib.stream 모듈을 찾을수 없다는 에러가 떠서,

python 소스에 추가해 주었습니다.

import talib
import talib.stream

 

이제 talib.stream오류는 해결되었나 봅니다.

다른 오류가 뜹니다.

KeyError: 'formatters'

 

원인을 보니, log config파일을 실행단계에서  logging.conf파일을 가져오지 못하는 오류인것으로 보입니다.

일반적으로 py파일을 실행할때는 아무 문제가 없던 부분입니다.

 

하기 붉은 색 부분을 os.path함수를 이용해서 명시적으로 path를 지정해 줍니다.

#!/usr/bin/python
# -*- coding: utf-8 -*-

import logging.config
from datetime import datetime
import os

class Logging():
    def __init__(self, config_path='config/logging.conf', log_path='log'):
        folderPath3 = os.path.abspath(os.getcwd()) + '/config'
        if not os.path.isdir(os.path.abspath(os.getcwd()) + '/config'):

           os.makedirs(os.path.abspath(os.getcwd()) + '/config')
        folderPath3 = str(folderPath3)
        config_path = os.path.abspath(folderPath3 + str("\\logging.conf"))

        folderPath3 = os.path.abspath(os.getcwd()) + '/log'
        if not os.path.isdir(os.path.abspath(os.getcwd()) + '/log'):

           os.makedirs(os.path.abspath(os.getcwd()) + '/log')
        log_path = str(folderPath3)
   
        self.config_path = config_path
        self.log_path = log_path

하지만, 소용이 없어 보입니다.

결국, pyinstaller에서 exe 실행파일 만들때는 log용 formater는 사용할 수가 없을 것 같습니다.

결국 모든 log 파일용 format 설정정보와 함수는 모두 지운후에 다시 실행해 보니, 정상적으로 exe파일이 실행됩니다.

pyinstaller --icon=.\image\goldcoin_1.ico --onefile --noconsole -F -n goldcoin.exe -c --clean main.spec

추가로, goldcoin.exe가 죽으면 계속해서 끊임없이 다시 실행시켜줄 ParentTrader.exe파일도 만들었습니다.

pyinstaller --onefile --noconsole -F -n ParentTrader.exe -c --clean ParentTrader.py

ParentTrader.exe를 실행하니, 다음과 같은 command창이 뜨면서 main창이 뜹니다.

여기서 "빗썸코인거래 시작"버튼을 누르면, 빗썸으로 자동접속되면서 매수추천 및 자동매매가 시작됩니다.

폴더내의 전체 파일 및 하위폴더 구조입니다.

반응형

댓글()

auto-py-to-exe로 python exe 파일 만들기

카테고리 없음|2021. 3. 7. 09:19
반응형

python 코드를 exe 배포파일 만들때는 pyinstaller를 사용합니다만,

옵션들을 직접 알고 타이핑해야 하는 불편함이 있었습니다.

 

그런데, 오늘..

출처: https://iamaman.tistory.com/3289 [남성의 MATLAB LOG]

님의 덕분에 좋은 방법을 찾게 되었습니다.

 

아래와 같이 anaconda prompt에서 pip install을 통해서 auto-py-to-exe를 설치해 줍니다.

그다음, auto-py-to-exe를 실행시키면 됩니다.

그러면, 다음과 같이 팝업 윈도우 창에서 실행파일 만드는 명령을 줄 수 있습니다.

약 10분 후에 정상적으로 완료되었다는 메세지가 보입니다.

이번에는 exe파일이 정상적으로 실행될 수 있을까요? 

지금까지 계속 실패하고 있거든요. exe파일 실행해도 에러 메세지도 없이 실행이 안되었거든요...

 

OPEN OUTPUT FOLDER를 눌러서 가니,

main.exe파일이 정상적으로 만들어져 있습니다. 실행을 해 볼까요?

에고.. 역시 또 실패입니다. numpy.random.common 모듈을 못찾았다네요.. 흠..

이거 오류 찾아서 결과 다시 올리겠습니다.

반응형

댓글()

파이썬에서 텔레그램 챗봇 API를 통한 주식매매정보 보내기

AI주식자동매매|2021. 1. 24. 11:03
반응형

안녕하세요?

주식자동매매 프로그램을 만들고 나면, 추천종목정보나 체결정보를 메신저로 받아보고 싶으실텐데,

Slack이나 텔레그램봇을 이용하여 쉽게 구현이 가능했습니다.

 

이번에는 가장 쉬운, 텔레그램챗봇을 만들어서 추천종목을 공유하는 방법을 정리해 보겠습니다.

자동매매프로그램에서 텔레그램에 정보를 보내기 위해서 꼭 필요로 하는 정보는 Bot Token 및 Chat Id 입니다.

Telegram API 를 이용하여 Bot Token(발신인) 이 Chat Id(수신인) 으로 메시지를 보내는 개념입니다.

 

 

1. 모바일 텔레그램의 대화방 탭에서 BotFather를 검색합니다.

   

2. BotFather를 선택하면 안내문이 나타납니다.  대충 내용 확인하시고, /start를 입력해 줍니다.

   

3. 대화창에서 /newbot 를 입력하여 새로운 봇을 만듭니다.

3. name 과 username 을 입력합니다.

  이때 name 은 말 그대로 봇을 부르는 이름으로 내가 알아보기 쉽게 지으면 됩니다.

   (나중에 /setname 명령으로 수정할 수도 있으니 name은 가볍게 지으시면 됩니다.)

   username 은 일종의 id 와 같은 개념으로 반드시 bot 으로 끝나야하며(TetrisBot or tetris_bot), 기존에 텔레그램에 등     록되어있는 username 은 사용할 수 없으므로 신중히 생각해서 입력하시기 바랍니다. 중복되면 안됩니다.

저는 name과 username을 똑 같이 입력해 버렸네요. 귀찮아서.. ㅎㅎ

username까지 입력하면, 다음과 같이 HTTP API정보를 보내줍니다. 숫자:알파벳 내용으로 되어 있습니다.

이 값이 Token입니다. 보안을 유의해서 잘 보관해 둡니다. 

4. 이제 메시지의 발신인이 될 봇을 만들고 봇의 Token 값을 알았으니,

   메시지의 수신인이 될 나의 Chat Id 를 확인하셔야 합니다.

   브라우저 주소 입력창에 https://api.telegram.org/bot봇Token값/getUpdates 를 입력합니다.

   "봇Token값" 위치에 3번에서 확인받은 Token값을 모두 full로 입력합니다.

  그러면, 그림이 너무 작긴 하지만, ,"chat":{"id": 뒤의 숫자정보가 본인의 chat_id입니다.

 

5. 이제 대화를 시작해야 할 수 있습니다.

   앞서 봇을 만들었던 BotFather 와의 대화창에서 t.me/??????bot 를 누르면 아래와 같은 대화창이 뜨고

   여기서 반드시 START(또는 시작) 를 눌러 텔레그램봇과의 대화를 시작할 수 있습니다.

6. 이제 파이썬 프로그램에서 token정보와 chat id를 이용해서 주식정보를 보내보겠습니다.

   보안때문에 token정보와 chat id는 가상의 정보이니 참고 바랍니다.

   하기는 소스의 해당 부분만을 적었습니다.

   추천종목정보의 종목코드(종목명), 현재가, 목표가, 목표가 매매시 예상수익률 관련 정보와

   해당 주봉, 일봉, 5분봉 정보 chart를 보내는 예제입니다. 

import telegram
.
.
class 
Kiwoom(QAxWidget, metaclass=Singleton):
   def __init__(self, parent=None, **kwargs):
        super().__init__(parent, **kwargs)
        .
        .
 
        self
.token = "219999999:AAZZZZZZZzzzzzzzzzZZZZZZ9UI"
        self.bot = telegram.Bot(self.token)
   
   def call_show_canvas(self):
        .
        .
        .
        try:
            self.bot.sendMessage(chat_id=218888888, text="(%s)기준 매수추천 종목입니다. 실제 매수여부는 각자가 판단하셔 
                                                                           야 합니다
." % (recomm_interval))
            self.bot.sendMessage(chat_id=218888888, text="%s(%s) %s, 현재가:%s, 목표가:%s(%s프로)" %           
                                             (stockName
, stockCode, market_status, current_price, target_sell_price, target_sell_rate))
       except:
            self.logging.logger.debug('chat_id: {}; error: {}'.format('1440986979', 'Error while sending notification'))

       .
       .
       .
      try:
           self.bot.send_photo(chat_id=218888888, photo=open(pic, 'rb')) #
      except:
           pass

 

실제 프로그램을 실행시켜보면, 다음과 같이 정상적으로 텔레그램봇이 주식정보를 받는 모습을 확인하실 수 있습니다.

1월 24일 기준으로 효성첨단소재 종목을 매수하라고 하네요. 

187,000원에 매입하면, 목표가 233,000원에 매도하여 24.3%의 수익률을 낼 수 있다네요..  맞을까요? ㅎㅎ

(무조건 따라 하시면 안됩니다.. 아래 메세지 경고문 참조하시구요.. ^^)

 

이상입니다~~ 

반응형

댓글()

TypeError: can't compare offset-naive and offset-aware datetimes

반응형

파이썬 프로그램에서 날자값을 비교하다보면 자주 접하는 오류가 

TypeError: can't compare offset-naive and offset-aware datetimes 인것 같습니다.

 

Error Code:

last_time = pd.to_datetime(self.chart_data[stockCode][-1:].time[0])
now = datetime.now()

if self.prev_time == last_time or self.prev_time >= last_time: # TypeError 발생부분
return

해결방법은 다음과 같습니다.

 

원인: 파이썬에서는 기본적으로 datetime 오브젝트는 aware가 아닌 "naive" 타입입니다.

        그래서, 비교 하려는 두 값 모두 같은 type의 오브젝트 여야 합니다.

 

Sampe Code:

import datetime
import pytz utc=pytz.UTC

challenge.datetime_start = utc.localize(challenge.datetime_start)

challenge.datetime_end = utc.localize(challenge.datetime_end)

# 이제 두개의 datetime 오브젝트는 모두 aware 타입이 되었으므로 비교가 가능합니다.

헷갈리시면, 다음과 같이 사용하셔도 됩니다.

start_time = challenge.datetime_start.replace(tzinfo=utc)
end_time = challenge.datetime_end.replace(tzinfo=utc)

 

참고로, datetime.timezone에 대해서 알아볼께요.

UTC를 기준으로 시간이 빠르면 +시차, 시간이 느리면 -시차로 표시합니다.

시간대나라코드

UTC-5 미국(동부) EST
UTC 영국 GMT
UTC+8 대만 TW
UTC+9 대한민국 KST
UTC+9 일본 JST
UTC+10 오스트레일리아(동부) AEST
  • 나라별 시간대 차이에 대한 더 자세한 내용은 여기를 참고해주세요.

 

참조사이트:

stackoverflow.com/questions/15307623/cant-compare-naive-and-aware-datetime-now-challenge-datetime-end

 

Can't compare naive and aware datetime.now() <= challenge.datetime_end

I am trying to compare the current date and time with dates and times specified in models using comparison operators: if challenge.datetime_start <= datetime.now() <= challenge.datetime_end:...

stackoverflow.com

spoqa.github.io/2019/02/15/python-timezone.html

 

파이썬의 시간대에 대해 알아보기(datetime.timezone)

파이썬의 시간대에 대해서 알아봅니다.

spoqa.github.io

 

반응형

댓글()

Python data Type - Datetime

반응형

자주 사용하게 되지만, 자주 헷갈리는 Python의 자료형에 대해서 정리를 해 나가겠습니다.

오늘은 Datetime입니다.

 

주어진 String값을 DateTime형식으로 바꾸기: strptime

 

Example 1: string to datetime object

from datetime

import datetime

 

date_string = "21 June, 2018"

 

print("date_string =", date_string)

print("type of date_string =", type(date_string))

 

date_object = datetime.strptime(date_string, "%d %B, %Y")

 

print("date_object =", date_object)

print("type of date_object =", type(date_object))

 

실행경과>

date_string = 21 June, 2018
type of date_string = <class 'str'>
date_object = 2018-06-21 00:00:00
type of date_object = <class 'datetime.datetime'>

Example 2: string to datetime object

from datetime

import datetime

dt_string = "12/11/2018 09:15:32"

# Considering date is in dd/mm/yyyy format

dt_object1 = datetime.strptime(dt_string, "%d/%m/%Y %H:%M:%S")

print("dt_object1 =", dt_object1)

# Considering date is in mm/dd/yyyy format

dt_object2 = datetime.strptime(dt_string, "%m/%d/%Y %H:%M:%S")

print("dt_object2 =", dt_object2)

실행경과>

dt_object1 = 2018-11-12 09:15:32
dt_object2 = 2018-12-11 09:15:32

 

Format Code List

The table below shows all the format codes that you can use.

Directive Meaning Example
%a Abbreviated weekday name. Sun, Mon, ...
%A Full weekday name. Sunday, Monday, ...
%w Weekday as a decimal number. 0, 1, ..., 6
%d Day of the month as a zero-padded decimal. 01, 02, ..., 31
%-d Day of the month as a decimal number. 1, 2, ..., 30
%b Abbreviated month name. Jan, Feb, ..., Dec
%B Full month name. January, February, ...
%m Month as a zero-padded decimal number. 01, 02, ..., 12
%-m Month as a decimal number. 1, 2, ..., 12
%y Year without century as a zero-padded decimal number. 00, 01, ..., 99
%-y Year without century as a decimal number. 0, 1, ..., 99
%Y Year with century as a decimal number. 2013, 2019 etc.
%H Hour (24-hour clock) as a zero-padded decimal number. 00, 01, ..., 23
%-H Hour (24-hour clock) as a decimal number. 0, 1, ..., 23
%I Hour (12-hour clock) as a zero-padded decimal number. 01, 02, ..., 12
%-I Hour (12-hour clock) as a decimal number. 1, 2, ... 12
%p Locale’s AM or PM. AM, PM
%M Minute as a zero-padded decimal number. 00, 01, ..., 59
%-M Minute as a decimal number. 0, 1, ..., 59
%S Second as a zero-padded decimal number. 00, 01, ..., 59
%-S Second as a decimal number. 0, 1, ..., 59
%f Microsecond as a decimal number, zero-padded on the left. 000000 - 999999
%z UTC offset in the form +HHMM or -HHMM.  
%Z Time zone name.  
%j Day of the year as a zero-padded decimal number. 001, 002, ..., 366
%-j Day of the year as a decimal number. 1, 2, ..., 366
%U Week number of the year (Sunday as the first day of the week). All days in a new year preceding the first Sunday are considered to be in week 0. 00, 01, ..., 53
%W Week number of the year (Monday as the first day of the week). All days in a new year preceding the first Monday are considered to be in week 0. 00, 01, ..., 53
%c Locale’s appropriate date and time representation. Mon Sep 30 07:06:05 2013
%x Locale’s appropriate date representation. 09/30/13
%X Locale’s appropriate time representation. 07:06:05
%% A literal '%' character. %

 

보다 많은 예시와 설명을 하기에서 참조하시면 됩니다.

www.programiz.com/python-programming/datetime/strptime

반응형

댓글()