728x90
38커뮤니케이션은 장외주식, IPO 등 다양한 정보를 제공한다. 이 사이트를 통해서 IPO 예정인 기업들을 크롤링해보도록 하자.
IPO/공모 탭을 클릭해보면 승인종목, IR일정, 수요예측일정, 수요예측결과, 공모청약일정, 신규상장 등 다양한 정보들이 있다.
승인종목 탭의 내용을 크롤링해보자. 크게 어렵지 않으므로 주석은 생략한다.
import requests
from bs4 import BeautifulSoup
import pandas as pd
def get_IPO_approval_data_from_38():
fullUrl = 'http://www.38.co.kr/html/ipo/ipo.htm?key=1'
response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
html = response.text
soup = BeautifulSoup(html, 'html.parser')
data = soup.find('table', {'summary': '승인종목'})
approval_date_list = []
company_list = []
requisition_date_list = []
capital_list = []
sales_list = []
net_income_list = []
underwriter_list = []
industry_list = []
data = data.find_all('tr')[2:]
for row in range(0, len(data)):
data_list = data[row].text.replace('\xa0\xa0', '').split('\n')[1:-1]
if len(data_list) < 8:
continue
approval_date_list.append(data_list[0].strip())
company_list.append(data_list[1].replace('(유가)', '').strip())
requisition_date_list.append(data_list[2].strip())
capital_list.append(data_list[4].strip())
sales_list.append(data_list[5].strip())
net_income_list.append(data_list[6].strip())
underwriter_list.append(data_list[7].strip())
industry_list.append(data_list[8].strip())
approval = pd.DataFrame({'approval_date': approval_date_list,
'company': company_list,
'requisition_date': requisition_date_list,
'capital': capital_list,
'sales': sales_list,
'net_income': net_income_list,
'underwriter': underwriter_list,
'industry': industry_list})
return approval
if __name__ == '__main__':
approval = get_IPO_approval_data_from_38()
print(approval)
결과 값
approval_date capital ... sales underwriter
0 2020/01/09 2,919 ... 94,382 삼성증권
1 2020/01/09 6,900 ... 259,266 유안타증권
2 2019/12/30 32,500 ... 1,069 한국투자증권,엔에이치투자증권
3 2019/12/26 15,200 ... 31,438 미래에셋대우
4 2019/12/26 3,296 ... 40,933 미래에셋대우
5 2019/12/20 10 ... 0 신영증권
6 2019/12/13 50 ... 0 KB증권
7 2019/12/12 8,380 ... 4,854 한국투자증권
8 2019/12/12 18,081 ... 368,194 KB증권
9 2019/12/05 1,700 ... 16,549 교보증권
10 2019/11/26 21 ... 0 하나금융투자
11 2019/11/12 21 ... 0 SK증권
12 2019/11/07 4,513 ... 34,711 KB증권
13 2019/11/07 711 ... 24,046 삼성증권
14 2019/10/24 0 ... 0 미래에셋대우
15 2019/10/17 4,481 ... 891 엔에이치투자증권,삼성증권
16 2019/10/15 9,713 ... 2,527 미래에셋대우
17 2019/09/05 25,924 ... 229,357 신한금융투자,유진투자증권
다음으로 IR일정의 내용을 크롤링해보자. IR일정은 여러 페이지로 구성되어있다. 따라서 함수에 페이지 수를 변수로 받아 몇 번째 페이지까지 크롤링할지를 정할 수 있게 하였다.
import requests
from bs4 import BeautifulSoup
import pandas as pd
def get_IPO_IR_schedule_data_from_38(page=1):
total_data = []
for p in range(1, page + 1):
fullUrl = 'http://www.38.co.kr/html/fund/index.htm?o=ir&page=%s' % p
response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
html = response.text
soup = BeautifulSoup(html, 'lxml')
data = soup.find('table', {'summary': '기업IR일정'})
data = data.find_all('tr')[2:]
total_data = total_data + data
company_list = []
ir_date_list = []
location_list = []
band_list = []
underwriter_list = []
for row in range(0, len(total_data)):
data_list = total_data[row].text.replace('\xa0\xa0', '').replace('\t\t', '').split('\n')[1:-1]
if len(data_list) < 5:
continue
company_list.append(data_list[0].replace('(유가)', '').strip())
ir_date_list.append(data_list[1].strip())
location_list.append(data_list[3].strip() + ' / ' + data_list[4].strip())
band_list.append(data_list[5].strip())
underwriter_list.append(data_list[6].strip())
schedule = pd.DataFrame({'company': company_list,
'ir_date': ir_date_list,
'location': location_list,
'band': band_list,
'underwriter': underwriter_list})
return schedule
if __name__ == '__main__':
IR_schedule = get_IPO_IR_schedule_data_from_38()
print(IR_schedule)
결과 값
band ... underwriter
0 10,000~11,200 ... 교보증권
1 63,000~78,000 ... 한국투자증권
2 6,000~7,000 ... 미래에셋대우
3 10,500~13,000 ... 한국투자증권
4 70,000~80,000 ... 대신증권,KB증권
5 34,000~43,000 ... 삼성증권
6 15,000~19,000 ... 케이비증권
7 11,000~14,500 ... 한국투자증권
8 3,700~4,500 ... 아이비케이투자증권,BNK투자증권
9 14,500~16,500 ... 한국투자증권
10 24,000~27,200 ... NH투자증권,신한금융투자,삼성증권
11 5,000~5,000 ... NH투자증권,키움증권,하나금융투자,한국투자증권
12 17,000~20,000 ... 대신증권
13 5,000~6,000 ... 한국투자증권,BNK투자증권
14 3,800~4,200 ... 미래에셋대우
15 16,000~20,000 ... 키움증권,삼성증권
16 24,000~28,000 ... 한국투자증권,하나금융투자,KB증권,하이투자증권,유안타증권
17 7,400~8,400 ... 한국투자증권
18 8,000~10,000 ... 신영증권
19 36,000~48,000 ... 한국투자증권,DB금융투자
수요예측일정의 내용을 크롤링해보자. 이 탭도 여러 페이지로 구성되어있다. 따라서 함수에 페이지 수를 변수로 받아 몇 번째 페이지까지 크롤링할지를 정할 수 있게 하였다.
import requests
from bs4 import BeautifulSoup
import pandas as pd
def get_IPO_demand_schedule_data_from_38(page=1):
total_data = []
for p in range(1, page + 1):
fullUrl = 'http://www.38.co.kr/html/fund/index.htm?o=r&page=%s' % p
response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
html = response.text
soup = BeautifulSoup(html, 'lxml')
data = soup.find('table', {'summary': '수요예측일정'})
data = data.find_all('tr')[2:]
total_data = total_data + data
company_list = []
demand_date_list = []
band_list = []
price_list = []
ipo_amount_list = []
underwriter_list = []
link_list = []
for row in range(0, len(total_data)):
data_list = total_data[row].text.replace('\xa0', '').replace('\t\t', '').split('\n')[1:-1]
if len(data_list) < 6:
continue
company_list.append(data_list[0].replace('(유가)', '').strip())
demand_date_list.append(data_list[1].strip())
band_list.append(data_list[2].strip())
price_list.append(data_list[3].strip())
ipo_amount_list.append(data_list[4].strip())
underwriter_list.append(data_list[5].strip())
link_list.append('http://www.38.co.kr/html/fund/' +
str(total_data[row].find('a')).replace('amp;', '').split('href=".')[1].split('=&')[0])
schedule = pd.DataFrame({'company': company_list,
'demand_date': demand_date_list,
'band': band_list,
'price': price_list,
'ipo_amount': ipo_amount_list,
'underwriter': underwriter_list,
'link': link_list})
return schedule
if __name__ == '__main__':
demand_schedule = get_IPO_demand_schedule_data_from_38()
print(demand_schedule)
결과 값
band company ... price underwriter
0 2,700~3,100 서남 ... - 한국투자증권
1 2,000~2,000 신영스팩6호 ... - 신영증권
2 10,000~11,200 위세아이텍 ... - 교보증권
3 2,000~2,000 케이비스팩20호 ... - KB증권
4 2,000~2,000 하나금융스팩15호 ... - 하나금융투자
5 63,000~78,000 천랩 ... 40,000 한국투자증권
6 2,000~2,000 한화플러스스팩1호 ... 2,000 한화투자증권
7 6,000~7,000 피피아이 ... 7,000 미래에셋대우
8 70,000~80,000 브릿지바이오테라퓨틱스 ... 60,000 대신증권,KB증권
9 2,000~2,000 엔에이치스팩15호 ... 2,000 NH투자증권
10 10,500~13,000 메탈라이프 ... 13,000 한국투자증권
11 34,000~43,000 메드팩토 ... 40,000 삼성증권
12 2,000~2,000 하이스팩5호 ... 2,000 하이투자증권
13 2,000~2,000 대신밸런스스팩8호 ... 2,000 대신증권
14 2,000~2,000 유안타스팩6호 ... 2,000 유안타증권
15 15,000~19,000 신테카바이오 ... 12,000 케이비증권
16 11,000~14,500 제이엘케이인스펙션 ... 9,000 한국투자증권
17 2,000~2,000 IBKS스팩12호 ... 2,000 아이비케이투자증권
18 3,700~4,500 태웅로직스 ... 4,500 아이비케이투자증권,BNK투자증권
19 2,000~2,000 에스케이스팩5호 ... 2,000 SK증권
수요예측결과의 내용을 크롤링해보자. 이 탭도 여러 페이지로 구성되어있다. 따라서 함수에 페이지 수를 변수로 받아 몇 번째 페이지까지 크롤링할지를 정할 수 있게 하였다.
import requests
from bs4 import BeautifulSoup
import pandas as pd
def get_IPO_demand_result_data_from_38(page=1):
total_data = []
for p in range(1, page + 1):
fullUrl = 'http://www.38.co.kr/html/fund/index.htm?o=r1&page=%s' % p
response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
html = response.text
soup = BeautifulSoup(html, 'lxml')
data = soup.find('table', {'summary': '수요예측결과'})
data = data.find_all('tr')[2:]
total_data = total_data + data
company_list = []
demand_date_list = []
band_list = []
price_list = []
ipo_amount_list = []
competition_rate_list = []
commitment_list = []
underwriter_list = []
for row in range(0, len(total_data)):
data_list = total_data[row].text.replace('\xa0', '').replace('\t\t', '').split('\n')[1:-1]
if len(data_list) < 8:
continue
company_list.append(data_list[0].replace('(유가)', '').strip())
demand_date_list.append(data_list[1].strip())
band_list.append(data_list[2].strip())
price_list.append(data_list[3].strip())
ipo_amount_list.append(data_list[4].strip())
competition_rate_list.append(data_list[5].strip())
commitment_list.append(data_list[6].strip())
underwriter_list.append(data_list[7].strip())
result = pd.DataFrame({'company': company_list,
'demand_date': demand_date_list,
'band': band_list,
'price': price_list,
'ipo_amount': ipo_amount_list,
'competition_rate': competition_rate_list,
'commitment': commitment_list,
'underwriter': underwriter_list})
return result
if __name__ == '__main__':
demand_result = get_IPO_demand_result_data_from_38()
print(demand_result)
결과 값
band commitment ... price underwriter
0 63,000~78,000 - ... 40,000 한국투자증권
1 2,000~2,000 - ... 2,000 한화투자증권
2 6,000~7,000 2.47% ... 7,000 미래에셋대우
3 70,000~80,000 0.06% ... 60,000 대신증권,KB증권
4 2,000~2,000 - ... 2,000 NH투자증권
5 10,500~13,000 22.46% ... 13,000 한국투자증권
6 34,000~43,000 13.83% ... 40,000 삼성증권
7 2,000~2,000 - ... 2,000 하이투자증권
8 2,000~2,000 - ... 2,000 대신증권
9 2,000~2,000 - ... 2,000 유안타증권
10 15,000~19,000 1.32% ... 12,000 케이비증권
11 11,000~14,500 - ... 9,000 한국투자증권
12 2,000~2,000 - ... 2,000 아이비케이투자증권
13 3,700~4,500 2.53% ... 4,500 아이비케이투자증권,BNK투자증권
14 2,000~2,000 - ... 2,000 SK증권
15 14,500~16,500 - ... 13,000 한국투자증권
16 24,000~27,200 6.04% ... 18,000 NH투자증권,신한금융투자,삼성증권
17 2,000~2,000 - ... 2,000 아이비케이투자증권
18 2,000~2,000 - ... 2,000 유안타증권
19 5,000~5,000 43.20% ... 5,000 NH투자증권,키움증권,하나금융투자,한국투자증권
다음으로 공모청약일정의 내용을 크롤링해보자. 이 탭도 여러 페이지로 구성되어있다. 따라서 함수에 페이지 수를 변수로 받아 몇 번째 페이지까지 크롤링할지를 정할 수 있게 하였다.
import requests
from bs4 import BeautifulSoup
import pandas as pd
def get_IPO_public_schedule_data_from_38(page=1):
total_data = []
for p in range(1, page + 1):
fullUrl = 'http://www.38.co.kr/html/fund/index.htm?o=k&page=%s' % p
response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
html = response.text
soup = BeautifulSoup(html, 'lxml')
data = soup.find('table', {'summary': '공모주 청약일정'})
data = data.find_all('tr')[2:]
total_data = total_data + data
company_list = []
public_date_list = []
price_list = []
band_list = []
competition_rate_list = []
underwriter_list = []
for row in range(0, len(total_data)):
data_list = total_data[row].text.replace('\xa0', '').replace('\t\t', '').split('\n')[1:-1]
if len(data_list) < 6:
continue
company_list.append(data_list[0].replace('(유가)', '').strip())
public_date_list.append(data_list[1].strip())
price_list.append(data_list[2].strip())
band_list.append(data_list[3].strip())
competition_rate_list.append(data_list[4].strip())
underwriter_list.append(data_list[5].strip())
schedule = pd.DataFrame({'company': company_list,
'public_date': public_date_list,
'price': price_list,
'band': band_list,
'competition_rate': competition_rate_list,
'underwriter': underwriter_list})
return schedule
if __name__ == '__main__':
public_schedule = get_IPO_public_schedule_data_from_38()
print(public_schedule)
결과 값
band company ... public_date underwriter
0 2,700~3,100 서남 ... 2020.02.10~02.11 한국투자증권
1 2,000~2,000 신영스팩6호 ... 2020.02.03~02.04 신영증권
2 10,000~11,200 위세아이텍 ... 2020.01.29~01.30 교보증권
3 2,000~2,000 하나금융스팩15호 ... 2020.01.16~01.17 하나금융투자
4 2,000~2,000 케이비스팩20호 ... 2020.01.16~01.17 KB증권
5 63,000~78,000 천랩 ... 2019.12.17~12.18 한국투자증권
6 6,000~7,000 피피아이 ... 2019.12.16~12.17 미래에셋대우
7 2,000~2,000 한화플러스스팩1호 ... 2019.12.16~12.17 한화투자증권
8 70,000~80,000 브릿지바이오테라퓨틱스 ... 2019.12.12~12.13 대신증권,KB증권
9 2,000~2,000 엔에이치스팩15호 ... 2019.12.12~12.13 NH투자증권
10 10,500~13,000 메탈라이프 ... 2019.12.12~12.13 한국투자증권
11 2,000~2,000 하이스팩5호 ... 2019.12.11~12.12 하이투자증권
12 34,000~43,000 메드팩토 ... 2019.12.10~12.11 삼성증권
13 15,000~19,000 신테카바이오 ... 2019.12.09~12.10 케이비증권
14 2,000~2,000 대신밸런스스팩8호 ... 2019.12.09~12.10 대신증권
15 2,000~2,000 유안타스팩6호 ... 2019.12.09~12.10 유안타증권
16 11,000~14,500 제이엘케이인스펙션 ... 2019.12.02~12.03 한국투자증권
17 2,000~2,000 IBKS스팩12호 ... 2019.11.28~11.29 아이비케이투자증권
18 3,700~4,500 태웅로직스 ... 2019.11.26~11.27 아이비케이투자증권,BNK투자증권
19 2,000~2,000 에스케이스팩5호 ... 2019.11.25~11.26 SK증권
20 14,500~16,500 리메드 ... 2019.11.25~11.26 한국투자증권
21 24,000~27,200 코리아센터 ... 2019.11.21~11.22 NH투자증권,신한금융투자,삼성증권
22 2,000~2,000 IBKS스팩11호 ... 2019.11.21~11.22 아이비케이투자증권
23 2,000~2,000 유안타스팩5호 ... 2019.11.18~11.19 유안타증권
24 5,000~5,000 엔에이치프라임리츠 ... 2019.11.18~11.20 NH투자증권,키움증권,하나금융투자,한국투자증권
마지막으로 신규상장 탭의 내용을 크롤링해보자. 이 탭도 여러 페이지로 구성되어있다. 따라서 함수에 페이지 수를 변수로 받아 몇 번째 페이지까지 크롤링할지를 정할 수 있게 하였다.
import requests
from bs4 import BeautifulSoup
import pandas as pd
import numpy as np
def get_IPO_list_performance_data_from_38(page=1):
total_data = []
for p in range(1, page + 1):
fullUrl = 'http://www.38.co.kr/html/fund/index.htm?o=nw&page=%s' % p
response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
html = response.text
soup = BeautifulSoup(html, 'lxml')
data = soup.find('table', {'summary': '신규상장종목'})
data = data.find_all('tr')[2:]
total_data = total_data + data
company_list = []
list_date_list = []
price_list = []
open_price_list = []
close_price_list = []
for row in range(0, len(total_data)):
data_list = total_data[row].text.replace('\xa0', '').replace('\t\t', '').split('\n')[1:-1]
if len(data_list) < 9:
continue
company_list.append(data_list[0].replace('(유가)', '').strip())
list_date_list.append(data_list[1].strip())
price_list.append(data_list[4].strip())
open_price_list.append(data_list[6].strip())
close_price_list.append(data_list[8].strip())
list_performance = pd.DataFrame({'company': company_list,
'list_date': list_date_list,
'price': price_list,
'open_price': open_price_list,
'close_price': close_price_list})
list_performance['open_price'] = list_performance['open_price'].replace('-', np.nan)
list_performance['return_open'] = list_performance['open_price'].str.replace(',', '').replace('-', 0).astype(float) / list_performance['price'].str.replace(',', '').replace('-', 0).astype(float) - 1
list_performance['close_price'] = list_performance['close_price'].replace('-', np.nan)
list_performance['return_close'] = list_performance['close_price'].str.replace(',', '').replace('예정', 0).replace('-', 0).astype(float) / list_performance['price'].str.replace(',', '').replace('-', 0).astype(float) - 1
return list_performance
if __name__ == '__main__':
list_performance = get_IPO_list_performance_data_from_38()
print(list_performance)
결과 값
close_price company list_date ... price return_open return_close
0 예정 위세아이텍 2020/02/10 ... - NaN NaN
1 예정 하나금융스팩15호 2020/01/30 ... - NaN NaN
2 예정 케이비스팩20호 2020/01/30 ... - NaN NaN
3 2,000 한화플러스스팩1호 2019/12/27 ... 2,000 0.002500 0.000000
4 9,630 피피아이 2019/12/26 ... 7,000 0.571429 0.375714
5 38,500 천랩 2019/12/26 ... 40,000 0.073750 -0.037500
6 2,000 엔에이치스팩15호 2019/12/24 ... 2,000 0.000000 0.000000
7 33,800 메탈라이프 2019/12/24 ... 13,000 1.000000 1.600000
8 2,005 하이스팩5호 2019/12/23 ... 2,000 0.000000 0.002500
9 54,300 브릿지바이오테라퓨틱스 2019/12/20 ... 60,000 0.040000 -0.095000
10 35,900 메드팩토 2019/12/19 ... 40,000 0.000000 -0.102500
11 2,005 대신밸런스스팩8호 2019/12/19 ... 2,000 0.002500 0.002500
12 2,000 유안타스팩6호 2019/12/19 ... 2,000 0.002500 0.000000
13 16,700 신테카바이오 2019/12/17 ... 12,000 0.245833 0.391667
14 9,000 제이엘케이인스펙션 2019/12/11 ... 9,000 -0.055556 0.000000
15 6,110 태웅로직스 2019/12/10 ... 4,500 0.815556 0.357778
16 2,050 IBKS스팩12호 2019/12/09 ... 2,000 0.020000 0.025000
17 13,450 리메드 2019/12/06 ... 13,000 0.084615 0.034615
18 2,010 에스케이스팩5호 2019/12/05 ... 2,000 0.005000 0.005000
19 6,500 엔에이치프라임리츠 2019/12/05 ... 5,000 0.000000 0.300000
728x90
'Data Science > Data Collection' 카테고리의 다른 글
[03. API] 002. FinanceDataReader (0) | 2020.02.12 |
---|---|
[03. API] 001. Pandas Datareader (0) | 2020.02.12 |
[02. 웹크롤링] 003. 야후 파이낸스 프랑스 – 주가 데이터 (0) | 2020.01.11 |
[02. 웹크롤링] 002. 야후 파이낸스 일본 – 주가 데이터 (0) | 2020.01.11 |
[02. 웹크롤링] 001. 네이버 – 주가 데이터 (0) | 2020.01.05 |