본문 바로가기

파이썬

[파이썬] 네이버증권 테마종목 크롤링 (2-2) beautifulsoup4 크롤링

지난 글에서 모든 테마 이름과, 테마 번호까지 얻었다.

 

그리고 그 테마에 접근하는 url의 규칙 또한 알고 있다.

 

<https://finance.naver.com/sise/sise_group_detail.naver?type=theme&no=XXX>

 

num이라는 list에 테마 넘버가 다 들어가 있고,

그것을 위 url의 XXX 부분에 대입하면 된다.

 

1번 글에서 확인했듯이 회사명은 <p info_title>에, 설명은 <strong class=’info_txt’>에 있다.

 

그렇게 얻은 데이터를 string으로 처리하는 과정에 대한 설명을 생략하고 코드를 보면 아래와 같다.

detail_url = "<https://finance.naver.com/sise/sise_group_detail.naver?type=theme&no=>"
now = detail_url+'36'
res = requests.get(now)
soup = bs(res.text, 'lxml')

info = soup.find_all('p', attrs={"class": "info_txt"}) #회사 설명
company = soup.find_all('strong', attrs={"class": "info_title"}) #회사명

for i in range(len(company)):
    name = str(company[i]) # 회사명을 string으로 바꿈

		#쓸데없는 부분 제거해서 company[i]에 입력
    front = name.find('info_title">') + len('info_title">')

    end = name.find("")

    company[i] = name[front:end]
		
		#쓸데없는 부분 제거해서 inf[i]에 입력
    inf = str(info[i])

    front = inf.find('"info_txt">') + len('"info_txt">')
    end = inf.find('')

    info[i] = inf[front:end]

    #print(info[1])

info_t.append(info)
comp_t.append(company)

 

‘해운’ 테마에 속하는 36번을 예시로 코드를 구성하였다.

 

이렇게 해서 info_title과 info_txt을 info_t 와 comp_t에 저장하면 흥미로운 결과가 나온다.

 

#print(comp_t[0])

['해운', '흥아해운', '대한해운', 'HMM', '팬오션', 'STX그린로지스', 'KSS해운']

#print(info_t[0][0:2])

['해운업종은 대표적인 경기민감주이자 중국관련주로서 세계해상 물동량에 의해 기본적 수요 규모가 결정되므로 중국을 비롯한 세계 경기변동과 밀접한 상관관계를 갖고 있음. 또한, 이스라엘-하마스 전쟁으로 인해 수에즈 운
하 등 홍해 물류 대란이 발생함에 따른 해상운임 상승으로 수혜가 전망되고 있음. 아울러 비용의 대부분을 연료유가 차지하고 있어 대표적인 유가민감주이며, 환율 하락시 선박투자관련 차입금 및 이자비용 감소 효과로 인해
 환율하락 수혜주로도 분류되고 있음.',
 '아시아지역 내에서의 액체석유화학제품을 운반하는 해운 운송서비스업을 주된 사업으로 영위중.']

 

바로 info_title과 info_txt의 0번째 index는 해당 테마의 title과 테마에 대한 설명이 들어간다는 것이다.

 

1번째 index부터 종목명과, 종목에 대한 설명이 나온다.

 

테마명과, 테마 설명에 해당하는 html 헤더를 따로 찾을 필요 없이 완성되었다.

 

2-1의 내용이 중복되어 대부분 생략했다.

 

이제 원하는 데이터는 다 크롤링 및 데이터화 했고 엑셀에 옮기면 마무리이다.

 

위 코드를 테마 갯수인 280번 반복하는 코드는 아래와 같다. 코드는 2-1에서 만든 코드를 포함한다.

 

import pandas as pd
import numpy as np
import math
import requests
from bs4 import BeautifulSoup as bs
import csv
import time
import re

import random
import openpyxl
import os

#######################################
# # 2-1에 해당하는 부분 # #
#######################################
url = "<https://finance.naver.com/sise/theme.naver>"

page_url = "<https://finance.naver.com/sise/theme.naver?&page=>"
detail_url = "<https://finance.naver.com/sise/sise_group_detail.naver?type=theme&no=>"

# res = requests.get(url)
# print(res.raise_for_status())
# soup = bs(res.text, "lxml")

num = []
urls = []
name = []

cnt_temp = 0

for j in range(1,9):
    now = page_url+str(j)
    res = requests.get(now)
    soup = bs(res.text, 'lxml')

    theme_name_s = soup.find_all('td', attrs={"class": "col_type1"})
    #theme_name = theme_name_s.find_all('a')

    for i in theme_name_s:
        front = 'amp;no='
        a = str(i)
        
        theme_num = str(a[a.find(front)+len(front):a.find(front)+len(front)+4])

        theme_num = re.sub(r'[^0-9]', '', theme_num)

        front = 'no=' + str(theme_num) + '">'
        end = ''

        theme_name = str(a[a.find(front)+len(front):a.find(end)])
        #print(theme_num)
        num.append(theme_num)
        name.append(theme_name)

        if cnt_temp == 3:
            break;
        cnt_temp += 1

    break
    time.sleep(1)
    print(j, ": done")
print("--------------------------------")

for i in num:
    urls.append(detail_url+str(i))

#print(name)

#print(len(num))
#print(urls[1])
# 테마 번호 추출 완료

#######################################
# # 데이터 추출 시작 2-2에 해당하는 부분 시작
#######################################

# print(len(company))
# print(info[1])
# print(company[1])

print("url finish")
print("url cnt : " + str(len(urls)))
cnt =0;

info_t = []
comp_t = []

for j in urls:
    now = j
    res = requests.get(now)
    soup = bs(res.text, 'lxml')

    info = soup.find_all('p', attrs={"class": "info_txt"})
    company = soup.find_all('strong', attrs={"class": "info_title"})

    for i in range(len(company)):
        name = str(company[i])

        front = name.find('info_title">') + len('info_title">')

        end = name.find("")

        company[i] = name[front:end]

        #print(company[1])

        inf = str(info[i])

        front = inf.find('"info_txt">') + len('"info_txt">')
        end = inf.find('')

        info[i] = inf[front:end]

        #print(info[1])

    info_t.append(info)
    comp_t.append(company)
    time.sleep(random.random()+0.1)

    if cnt%50 == 0:
        print(cnt, ": done")
    cnt +=1

print(info_t[0][0:2])

# ====================== 크롤링 끝

 

중요한 건 다 끝났고 이제 데이터를 excel로 저장하면 완료이다.