마스터욱
Toggle navigation
  • 회원가입 | 정보찾기
ICON NAVIGATION
정보수정 쪽지함 주변맛집 익명채팅
공지사항 채팅 개발문의 방명록
  • MAIN NAVIGATION
  • 메인
  • 마스터욱 공간
    • 마스터욱 소개
    • 개발 리스트
    • 공지사항
    • 방명록
  • 마스터욱 외부자료
    • 네이버
    • 티스토리
    • 깃허브(github)
  • 개인 프로젝트
    • 랜덤 이성 채팅
    • Auto 크롤링
    • Javascript 카카오 채팅
    • 파이썬 뉴스매매
    • C# 키움 주식 자동매매
    • C# 키움 주식 패턴 분석
    • PHP 욱보드
    • 업비트 자동매매 개발
    • 업비트 자동매매 일지
  • 개발 의뢰
    • 개발 문의
    • 개발 견적
    • 개발 피드백
    • FAQ
  • 개발 경험 Tip
    • PHP
    • JSP
    • HTML
    • Javascript
    • Android
    • C#
    • MySQL
    • Linux
    • Python
    • NodeJS
    • React
    • Vue.js
    • Flutter
    • 정규식
    • 기타
  • 커뮤니티
    • 자유게시판
    • 추천사이트
    • 영화
    • 여행
    • 유머
    • Overseas News
  • 맛집&즐길 거리 탐방
    • 맛집 정보
    • 즐길 거리 정보
    • 내 주위 맛집&즐길 거리
  • 공유 사진
    • 음식
    • 여행
    • 캐릭터
    • 배경
    • 기타
    • 이모티콘
    • 일러스트
  • 놀이터
    • 블록뽀시기
    • 트레이딩뷰
    • 로또 시뮬레이션
    • 쳇쳇 익명 채팅
    • 랜덤 이성 채팅
    • AI 채팅
    • 미니 채팅
    • 바이너리 테스트
    • 마번호 생성기
    • 바카라 시뮬레이션
    • 홀짝점수 테스트
    • 로또 분석기
SITE STATISTICS
  • - 명 현재 접속자
  • 1,951 명 오늘 방문자
  • 2,745 명 어제 방문자
  • 5,192 명 최대 방문자
  • 679,300 명 전체 방문자
  • 2,569 개 전체 게시물
  • 496 개 전체 댓글수
Facebook Twitter GooglePlus KakaoStory NaverBand
  1. 홈
  2. 뉴스매매
목록으로

공시뉴스기사와 키워드 매칭작업

마스터욱 0 188 0 0 2018-03-22 15:11:00

공시뉴스기사와 키워드 매칭작업
 

 

뉴스기사와 키워드를 매칭하여 교집합이 발생하면 종목코드를 디텍팅하는 것까지 끝냈습니다.

매칭 알고리즘은 API 서버에서 처리하고, 로그만 리턴하여 클라이언트에서 뿌렸습니다.

클라이언트 소스 공개합니다.

import sys
import lib as lib
#import kiwoom as ki

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QAxContainer import *

#import pandas as pd
from pprint import pprint
import re
import requests
from threading import Timer, Thread, Event

import json
from collections import OrderedDict

import webbrowser
from functools import partial

class perpetualTimer():
def __init__(self, t, hFunction):
self.t = t
self.hFunction = hFunction
self.thread = Timer(self.t, self.handle_function)

def handle_function(self):
self.hFunction()
self.thread = Timer(self.t, self.handle_function)
self.thread.start()
self.thread.cancel()

def start(self):
self.thread.start()

def cancel(self):
self.thread.cancel()

class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("뉴스매매(Makeby 욱)")
self.setGeometry(300, 300, 1200, 700)
self.setTable()

#self.t = perpetualTimer(1, self.startNews)
#self.t.start()

#timer = QTimer()
#timer.timeout.connect(self.startNews)
#timer.start(1000)
self.current_timer = ""
#self.start_timer() #로그인후 실행하도록 변경

self.apiUrl = "API URL은 비밀"

self.thread_cnt = 0
self.last_title = ""

#키움개인정보
#self.user_id = "dev84" #테스트
self.user_id = ""

#print(sys.version)

#키움증권
self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")

self.kiwoom.OnEventConnect.connect(self.event_connect)
#self.kiwoom.event_connect_loop = QEventLoop()
#self.kiwoom.event_connect_loop.exec_()
#print(self.kiwoom)
#ki_instance = ki.Kiwoom()

self.btn1 = QPushButton("로그인", self)
self.btn1.move(1000, 20)
#btn1.clicked.connect(ki_instance.btn1_clicked)
self.btn1.clicked.connect(self.btn1_clicked)

btn2 = QPushButton("상태체크", self)
btn2.move(1100, 20)
#btn2.clicked.connect(ki_instance.btn2_clicked)
btn2.clicked.connect(self.btn2_clicked)

'''
self.ed = QLineEdit()
self.ed.move(700, 50)
self.ed.setText("홍길동") # 텍스트 쓰기
text = self.ed.text() # 텍스트 읽기
self.ed.setPlaceholderText("이름을 입력하시오") # Watermark로 텍스트 표시
self.ed.selectAll() # 텍스트 모두 선택
#ed.setReadOnly(True)# 에디트는 읽기 전용으로
#e.setEchoMode(QLineEdit.Password)# Password 스타일 에디트
'''
keywordLabel = QLabel("종목&키워드 매칭(종목코드:키워드1,키워드2,키워드3...)", self)
keywordLabel.setGeometry(510, 50, 500, 50)

self.keywordbtn = QPushButton("매칭 저장", self)
self.keywordbtn.move(1100, 60)
self.keywordbtn.clicked.connect(self.keywordbtn_clicked)

self.textEdit = QTextEdit(self)
self.textEdit.resize(670, 250)
self.textEdit.move(510, 100)


logLabel = QLabel("로그", self)
logLabel.setGeometry(510, 370, 500, 50)

self.textEdit2 = QTextEdit(self)
self.textEdit2.resize(670, 250)
self.textEdit2.move(510, 420)
#self.textEdit2.setReadOnly(True)

"""""
btn1 = QPushButton("Click me", self)
btn1.move(20, 20)
btn1.clicked.connect(self.btn1_clicked)
"""

def start_timer(self):
if self.current_timer:
self.current_timer.stop()
self.current_timer.deleteLater()

self.current_timer = QTimer()
self.current_timer.timeout.connect(self.startNews)
self.current_timer.setSingleShot(True)
self.current_timer.start(1000)

def keywordbtn_clicked(self):
#print("저장")
content = self.textEdit.toPlainText()
#print(content)
#print(self.user_id)

post_data = {"type": "keyword_save", "stock_id": self.user_id, "content": content}
r = requests.post(self.apiUrl, data=post_data)
result_json = r.text #{"result":"OK"}
#print(result_json)

# JSON 디코딩
dict = json.loads(result_json)
#print("result = " + dict['result']) #OK
if dict['result'] == "OK":
w = QWidget() # The QWidget widget is the base class
w.setWindowTitle('키워드저장버튼')
w.resize(400, 200)
result = QMessageBox.information(w, "Information", "저장완료")

#if result == QMessageBox.Ok:
# myTextbox.setText("Clicked OK on Information.")

def btn1_clicked(self):
#print("로그인 버튼 클릭")
ret = self.kiwoom.dynamicCall("CommConnect()")
if ret == 0:
self.statusBar().showMessage("로그인 창 열기 성공")
#self.btn1.setText('로그인 정보보기')
#self.getLoginInfo()
else:
self.statusBar().showMessage("로그인 창 열기 실패")
#print(ret)

def btn1_clicked_logined(self):
print("ok")

#로그인 상태 확인
def btn2_clicked(self):
if self.kiwoom.dynamicCall("GetConnectState()") == 0:
self.statusBar().showMessage("Not connected")
else:
self.statusBar().showMessage("Connected")

#로그인 유저 정보 호출
def getLoginInfo(self, type):
#print("getLoginInfo")
info = self.kiwoom.dynamicCall("GetLoginInfo(QString)", type)
#print(info)
return info

#로그인 후 실행되는 함수
def event_connect(self, code):
if code == 0:
self.statusBar().showMessage("로그인 성공")
self.user_id = self.getLoginInfo("USER_ID")
self.btn1.setText(self.user_id + "님 로그인중");
#버튼 이벤트 해제해야 하는데 일단 스킵

#종목코드:키워드 정보 가져오기
post_data = {"type":"get_keyword", "stock_id":self.user_id}
r = requests.post(self.apiUrl, data=post_data)
result_json = r.text #{"result":"OK"}

# JSON 디코딩
dict = json.loads(result_json)
data = dict['data']
print("종목키워드 데이터 = " + data)
self.textEdit.setText(data)

self.start_timer()
else:
self.statusBar().showMessage("로그인 실패")

#print("event_connect 호출됨")
#self.event_connect_loop.exit()

def setTable(self):
#self.setGeometry(5,5,200,200)

newsLabel = QLabel("실시간 뉴스", self)
newsLabel.setGeometry(5, 5, 500, 50)

self.tableWidget = QTableWidget(self)

#self.tableWidget.resize(500, 500)
self.tableWidget.setGeometry(5, 50, 500, 500)

self.tableWidget.setRowCount(20)
self.tableWidget.setColumnCount(3)

#self.tableWidget.setVerticalHeaderLabels(['1','2'])
self.tableWidget.setHorizontalHeaderLabels(['제목', '시간', '상세보기'])

#데이터 넣기
#self.setTableWidgetData()
#self.startNews()

def startNews(self):
self.thread_cnt = self.thread_cnt + 1
print("뉴스 쓰레드 가동(" + str(self.thread_cnt) + ")")

#뉴스 쓰레드 가동(283) 에서
#Process finished with exit code -1073740940 (0xC0000374) 에러발생
#Process finished with exit code -1073741819 (0xC0000005)
#Process finished with exit code -1073741819 (0xC0000005)

#뉴스 저장하기
#self.setNews2()

#뉴스 가져오기
#self.getNews()

#뉴스 쓰레드 가동(281) 에서
#Process finished with exit code -1073740940 (0xC0000374)
self.getSetNews()

#self.t = perpetualTimer(1, self.startNews)
#self.t.start()

#timer = QTimer()
#timer.timeout.connect(self.startNews)
#timer.start(1000)

self.start_timer()

'''
def setTableWidgetData(self):
self.tableWidget.setItem(0, 0, QTableWidgetItem("(0,0)"))
self.tableWidget.setItem(0, 1, QTableWidgetItem("(0,1)"))
self.tableWidget.setItem(1, 0, QTableWidgetItem("(1,0)"))
self.tableWidget.setItem(1, 1, QTableWidgetItem("(1,1)"))
'''

"""
def btn1_clicked(self):
QMessageBox.about(self, "message", "clicked")
"""

#API 서버에서 뉴스크롤링 실행시키고, 바로 가져오기
def getSetNews(self):
post_data = {"type": "getset", "stock_id": self.user_id}
r = requests.post(self.apiUrl, data=post_data)
result_json = r.text #{"result":"OK"}

# JSON 디코딩
dict = json.loads(result_json)
#print("getsetNews = " + dict['result'])

#매칭된 키워드가 있으면 로그로 보여주기
'''
뉴스 쓰레드 가동(135)
{'111': ['(주)', '결과']}
'''
if dict['log_text']:
content = self.textEdit2.toPlainText()
self.textEdit2.setText(dict['log_text'] + content)

#print(dict['list'])
cnt = 0
#self.tableWidget.setRowCount(20)

for row in dict['list']:
if cnt == 0:
if self.last_title == row['title']:
break
else:
#print(row['title'] + " " + row['time'])
self.last_title = row['title']
#for i in range(0, 20):
# self.tableWidget.setItem(i, 0, QTableWidgetItem("1"))
# self.tableWidget.setItem(i, 1, QTableWidgetItem("1"))

title = row['title'][0:30]
self.tableWidget.setItem(cnt, 0, QTableWidgetItem(title))
self.tableWidget.setItem(cnt, 1, QTableWidgetItem(row['time']))

detailbtn = QPushButton("보기")
#detailbtn.clicked.connect(lambda:self.detailbtn_clicked(row['idx']))
detailbtn.clicked.connect(partial(self.detailbtn_clicked, row['idx']))
self.tableWidget.setCellWidget(cnt, 2, detailbtn)
#print(row['idx'])

#데이터 갱신을 위해 포커스를 주자
self.tableWidget.setCurrentCell(cnt, 0)
self.tableWidget.setCurrentCell(cnt, 1)
self.tableWidget.setCurrentCell(cnt, 2)
cnt = cnt + 1

#각 열크기 맞춤
self.tableWidget.resizeColumnsToContents()
self.tableWidget.resizeRowsToContents()

#기사 상세보기 띄우기
def detailbtn_clicked(self, idx):
#print(idx)
url = self.apiUrl + "?type=news_detail&idx=" + idx + "&stock_id=" + self.user_id
webbrowser.open(url)

#API 서버에서 뉴스크롤링 실행시키기
def setNews2(self):
post_data = {"type": "set", "stock_id": self.user_id}
r = requests.post(self.apiUrl, data=post_data)
result_json = r.text #{"result":"OK"}

# JSON 디코딩
dict = json.loads(result_json)
print("setNews2 = " + dict['result'])


#파이썬 자체에서 크롤링
def setNews(self):
#공시정보 가져오기
#lib.get_financial_statements('http://dart.fss.or.kr/api/search.json?auth=5d7fe977e575fb2ec15661d0a1556f40793237f6')
outhtml = lib.get_financial_statements('크롤링 주소는 비밀')
#print(outhtml)
#output = re.match(r'(?s).*<!-- List BBS Block Start -->(.*)<!-- //List BBS Block End -->.*', outhtml, re.M|re.I)
#print(output.group(1))
#output = re.match(r'(?s).*<div class="newListArea">(.*)</div>(.*)</div>.*', output.group(1), re.M|re.I)
output = re.match(r'(?s).*<!-- %%LIST data%% -->(.*)<!-- %%ENDLIST data%% -->.*', outhtml, re.M | re.I)
output_data = ''
if output is not None:
output_data = output.group(1)
#print(output)
else:
print("젠장... 비었음...")

#print(output_data)
outlist = re.split('</tr>', output_data)
#pprint(outlist)

cnt = 0
all_json = OrderedDict()
for row in outlist:
#date = lib.get_between_string(row, '<div id="date_0">', '</div>')
#print(row)
row_list = re.split('<td', row)
#pprint(row_list)
#print(row_list[2])
#print(lib.strip_tags(row_list[3]))
#print(row_list[3])
date = ''
time = ''
title = ''
try:
row_json = OrderedDict()
tmp = re.match(r'(?s).*<div id="date_.*">(.*)</div></td>.*', row_list[1])
date = tmp.group(1)

tmp = re.match(r'(?s).*<div id="time_.*">(.*)</div></td>.*', row_list[2])
time = tmp.group(1)

tmp = re.match(r'(?s).*<div id=\'title_.*\'>(.*)</div></a>.*', row_list[3])
title = tmp.group(1)
title = title.replace('&nbsp; ','')

row_json['date'] = date
row_json['time'] = time
row_json['title'] = title

all_json[str(cnt)] = row_json
except:
'''
print("끝줄에러")
'''

'''
test = ""
test += "date = " + date + " || "
test += "time = " + time + " || "
test += "title = " + title + " || "
print(str(cnt) + " = " + test)
'''
cnt = cnt + 1


#pprint(all_json)
jsonString = json.dumps(all_json)
post_data = {'data': jsonString, "type": "news_toss", "stock_id": self.user_id}
#print(jsonString)
#pprint(post_data)

#디비에 저장
r = requests.post(self.apiUrl, data=post_data)
result_json = r.text #{"result":"OK"}


def getNews(self):
post_data = {"type": "get", "stock_id": self.user_id}
r = requests.post(self.apiUrl, data=post_data)
result_json = r.text #{"result":"OK"}
#print("result_json = " + result_json)

# JSON 디코딩
dict = json.loads(result_json)

# Dictionary 데이타 체크
print("getNews = " + dict['result'])

#print(dict['list'])
cnt = 0
#self.tableWidget.setRowCount(20)

for row in dict['list']:
if cnt == 0:
if self.last_title == row['title']:
break
else:
#print(row['title'] + " " + row['time'])
self.last_title = row['title']
#for i in range(0, 20):
# self.tableWidget.setItem(i, 0, QTableWidgetItem("1"))
# self.tableWidget.setItem(i, 1, QTableWidgetItem("1"))

title = row['title'][0:40]
self.tableWidget.setItem(cnt, 0, QTableWidgetItem(title))
self.tableWidget.setItem(cnt, 1, QTableWidgetItem(row['time']))

#데이터 갱신을 위해 포커스를 주자
self.tableWidget.setCurrentCell(cnt, 0)
self.tableWidget.setCurrentCell(cnt, 1)
cnt = cnt + 1

#각 열크기 맞춤
self.tableWidget.resizeColumnsToContents()
self.tableWidget.resizeRowsToContents()


if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
app.exec_()
0
0

목록

Facebook Twitter GooglePlus KakaoStory NaverBand
0 Comments

비밀번호 확인

확인
댓글은 자신을 나타내는 '얼굴'입니다. *^^*
등록
자동등록방지 숫자를 순서대로 입력하세요.

댓글수정


번호 제목 이름 날짜 조회
  • 21
    [11] 파이썬 공시뉴스 자동매매 프로그램 ver2.0 [11]
    마스터욱
    조회수 348   18-05-03 23:36
    마스터욱
    18-05-03 23:36
    348
  • 20
    키움API, 나의 매수리스트 불러오기
    마스터욱
    조회수 223   18-04-15 01:48
    마스터욱
    18-04-15 01:48
    223
  • 19
    Qt Designer XML 을 py 소스로 변경작업
    마스터욱
    조회수 168   18-04-10 17:39
    마스터욱
    18-04-10 17:39
    168
  • 18
    관리종목 필터링 추가
    마스터욱
    조회수 143   18-04-10 00:36
    마스터욱
    18-04-10 00:36
    143
  • 17
    파이썬 뉴스 자동매매, 매수리스트 완료
    마스터욱
    조회수 186   18-04-09 18:58
    마스터욱
    18-04-09 18:58
    186
  • 16
    뉴스자동매매, 매수로직 적용완료
    마스터욱
    조회수 230   18-04-09 00:46
    마스터욱
    18-04-09 00:46
    230
  • 15
    실시간 뉴스, 종목 키워드, 주문 설정, 매수 패턴 적용완료
    마스터욱
    조회수 160   18-04-08 01:05
    마스터욱
    18-04-08 01:05
    160
  • 14
    종목코드 데이터베이스에 저장
    마스터욱
    조회수 162   18-04-04 15:34
    마스터욱
    18-04-04 15:34
    162
  • 13
    파이썬을 이용한 뉴스매매 ver2.0 실시간 뉴스 + 주문설정 페이지 제작완료
    마스터욱
    조회수 187   18-04-04 00:07
    마스터욱
    18-04-04 00:07
    187
  • 12
    키움 API를 이용한 뉴스매매 ver2.0 개발시작
    마스터욱
    조회수 173   18-04-02 01:11
    마스터욱
    18-04-02 01:11
    173
  • 11
    [2] 최종 완성본 이라기보다는 일단 프로토타입 완성 [2]
    마스터욱
    조회수 255   18-03-29 21:47
    마스터욱
    18-03-29 21:47
    255
  • 10
    매수성공
    마스터욱
    조회수 257   18-03-28 16:17
    마스터욱
    18-03-28 16:17
    257
  • 9
    매수 API가 안되길래 키움증권에 문의남김2.
    마스터욱
    조회수 208   18-03-27 17:57
    마스터욱
    18-03-27 17:57
    208
  • 8
    매수 API가 안되길래 키움증권에 문의남김.
    마스터욱
    조회수 270   18-03-26 19:43
    마스터욱
    18-03-26 19:43
    270
  • 7
    공시뉴스기사와 키워드 매칭작업
    마스터욱
    조회수 189   18-03-22 15:11
    마스터욱
    18-03-22 15:11
    189
  • 6
    공시뉴스 초단위로 불러오기, 쓰레드 문제 해결
    마스터욱
    조회수 244   18-03-21 14:09
    마스터욱
    18-03-21 14:09
    244
  • 5
    키움 로그인 창 띄우기
    마스터욱
    조회수 137   18-03-16 00:44
    마스터욱
    18-03-16 00:44
    137
  • 4
    개발에 도움받은 페이지 목록
    마스터욱
    조회수 160   18-03-15 13:52
    마스터욱
    18-03-15 13:52
    160
  • 3
    뉴스 크롤링 완료
    마스터욱
    조회수 189   18-03-14 20:05
    마스터욱
    18-03-14 20:05
    189
  • 2
    파이참(PyCharm) 설치
    마스터욱
    조회수 151   18-03-14 19:02
    마스터욱
    18-03-14 19:02
    151
  • 1
  • 2
  • 다음

Search

개인정보처리방침
마스터욱. All rights reserved.

Close

0 명 접속중
Time Loading...