Side Projects/공모주 알리미

[공모주 알리미 개발] 2-1. ipostock 크롤링 : 종목별 url 추출하기

hzoooo 2021. 8. 30. 15:47

공모주 관련 정보를 크롤링할 사이트로 38 커뮤니케이션, ipostock 두 가지를 알아봐 두었다.

그중, 먼저 아래 ipostock 사이트에서 공모주 관련 정보를 크롤링하려고 한다.

 

아이피오스탁(IPOSTOCK)-IPO공모주,K-OTC 장외시장

 

www.ipostock.co.kr


IPO 공모 탭 -> 공모 청약일정으로 들어오게 되면, 월별로 공모 일정 및 종목명, 공모가 등 간단한 정보들을 볼 수 있다.

 

크롤링을 위해 월별 탭을 눌러봤더니,

- sub03/ipo04.asp?str1=2021&str2=8

- sub03/ipo04.asp?str1=2021&str2=9

와 같이, 연월에 따라 table이 변함을 알 수 있었다.

 

종목명을 누르면 더 상세한 정보들을 볼 수 있는 페이지로 넘어가는데, 종목마다 다른 코드를 가지고 있기 때문에 하이퍼링크를 통해 종목별 페이지를 얻을 수 있었다.

이때 하이퍼링크에 /view_pg/ 가 공통인 점을 더보기 안의 사진과 같이 확인하여, 아래와 같이 코드를 작성하였다.

더보기
다른 종목들도 확인해보면, a 태그의 하이퍼링크 값으로 /view_pg/를 공통적으로 가지고 있다.

 

<종목별 기업 상세정보 url을 얻어오기 위한 코드>

import requests
from bs4 import BeautifulSoup
from datetime import datetime

def get_url_list(target_date):
    year = target_date.year
    month = target_date.month

    base_url = 'http://ipostock.co.kr'
    temp_url = f'http://ipostock.co.kr/sub03/ipo04.asp?str1={year}&str2={month}'
    response = requests.get(temp_url)
    temp_html = response.content.decode('utf-8', 'replace')
    temp_soup = BeautifulSoup(temp_html, 'lxml')

    company_name_a_tag_list = temp_soup.select("a[href^='/view_pg/']")
    url_list = []

    for a_tag in company_name_a_tag_list:
        url_list.append(base_url + a_tag.get('href'))

    return url_list

 


여기서 더 나아가서,

금일 기준 청약 시작 전, 시작, 마감일 및 상장 전일, 마감일에 대한 url(총 5개의 url list)만 가져오기 위해, 아래와 같이 코드를 작성했다.

<5가지 유형의 url 가져오기>

import requests
from bs4 import BeautifulSoup
from datetime import datetime

def get_url_list(target_date):
    year = target_date.year
    month = target_date.month

    base_url = 'http://ipostock.co.kr'
    temp_url = f'http://ipostock.co.kr/sub03/ipo04.asp?str1={year}&str2={month}'
    response = requests.get(temp_url)
    temp_html = response.content.decode('utf-8', 'replace')
    temp_soup = BeautifulSoup(temp_html, 'lxml')

    company_name_a_tag_list = temp_soup.select("a[href^='/view_pg/']")
    offering_period_td_list = temp_soup.select("td[width^='88']")
    # 테이블 열이름 td[0:3] -> 환불일, 상장일, 경쟁률 없애기
    temp_date_td_list = temp_soup.select("td[width^='60']")[3:]

    offering_before_day_url_list = []
    offering_start_url_list = []
    offering_finish_url_list = []
    ipo_before_day_url_list = []
    ipo_d_day_url_list = []

        for idx in range(0, len(offering_period_td_list)):
        offering_start_temp, offering_fin_temp = offering_period_td_list[idx].text.strip().replace('\xa0', '').split('~')
        ipo_date = temp_date_td_list[1 + 2 * idx].text.strip().replace(' ', '')

        offering_start = datetime.strptime(str(year) + '.' + offering_start_temp, "%Y.%m.%d")
        date_diff_offering_start = (target_date - offering_start).days
        is_offering_ready = True if (date_diff_offering_start >= -1 and date_diff_offering_start <= 1) else False

        try:
            ipo_start = datetime.strptime(str(year) + '.' + ipo_date, "%Y.%m.%d")
            date_diff_ipo_start = (target_date - ipo_start).days
            is_ipo_ready = True if (date_diff_ipo_start == -1 or date_diff_ipo_start == 0) else False

            url = base_url + company_name_a_tag_list[idx].get('href')

            if (not is_offering_ready) and (not is_ipo_ready):
                continue
            elif date_diff_offering_start == -1:
                offering_before_day_url_list.append(url)
            elif date_diff_offering_start == 0:
                offering_start_url_list.append(url)
            elif date_diff_offering_start == 1:
                offering_finish_url_list.append(url)
            elif date_diff_ipo_start == -1:
                ipo_before_day_url_list.append(url)
            elif date_diff_ipo_start == 0:
                ipo_d_day_url_list.append(url)
        except:
            url = base_url + company_name_a_tag_list[idx].get('href')
            if (not is_offering_ready):
                continue
            elif date_diff_offering_start == -1:
                offering_before_day_url_list.append(url)
            elif date_diff_offering_start == 0:
                offering_start_url_list.append(url)
            elif date_diff_offering_start == 1:
                offering_finish_url_list.append(url)

    return [offering_before_day_url_list,
            offering_start_url_list,
            offering_finish_url_list,
            ipo_before_day_url_list,
            ipo_d_day_url_list]

table 요소에 summary나, class가 정해져 있지 않아 공모 일정, 상장일 정보를 억지로 가져오느라 코드가 너무 지저분해졌다.

(물론 내 변수 naming이 길어서 그런 것 같기도 하다..)

try문을 넣은 이유는 청약이 상장보다 먼저 이루어지기 때문에 상장일이 비어있는 경우가 많으며,

보통 청약 시작 전일에 상장일이 정해지곤 하는데 안 정해진 경우, 상장일은 비교하지 않고 청약일만 비교하기 위하여 try, except 문을 넣었다.

 

글을 쓰는 당일(8/30)의 경우

- 와이엠텍은 청약 전일(offering_before_day_url_list) 리스트

- 에이비온/SK리츠는 청약 당일(offering_start_url_list) 리스트에 담겼다.

 

다음 글에서는, 종목별 url에서 청약 관련 정보들을 추출하는 방법을 포스팅 하려고 한다!


※회고

글을 쓰는 현재, ipostock에서 크롤링하도록 코드를 작성해두었지만 몇 가지 문제점이 있다는 걸 알았다.

  • 월말이 되면 추가로 다음 달 탭으로 넘어가서 청약 예정 종목을 추가로 탐색해야 된다.
  • 월 초에는 상장 예정 정보 종목을 전월 탭으로 넘어가서 가져와야 된다.