1. 테마 번호 추출
지난 글에서 종목을 찾은 것처럼 테마별 시세에서 각각의 테마를 의미하는 값을 보니 <td class=”col_type1”>안에 테마 넘버가 있다.
import requests
from bs4 import BeautifulSoup as bs
url = "<https://finance.naver.com/sise/theme.naver>"
page_url = "<https://finance.naver.com/sise/theme.naver?&page=>"
num = []
urls = []
name = []
now = page_url+"1"
res = requests.get(now)
soup = bs(res.text, 'lxml')
theme_list = soup.find_all('td', attrs={"class": "col_type1"})
for i in theme_list:
print(i)
현재 보고 있는 첫 페이지(page=1)만 처리하는 코드
url = “naver.com/(생략)&page=1” 이다
theme_list = soup.find_all('td', attrs={"class": "col_type1"})
그리고 거기서 아까 찾아놓은 위치 <td class=”col_type1”>을 find_all을 이용해서 모두 찾으면 아래와 같은 결과를 얻을 수 있다.
for i in theme_list:
print(i)
--<print result>--
<td class="col_type1"><a href="/sise/sise_group_detail.naver?type=theme&no=36">해운</a></td>
<td class="col_type1"><a href="/sise/sise_group_detail.naver?type=theme&no=557">유리 기판</a></td>
<td class="col_type1"><a href="/sise/sise_group_detail.naver?type=theme&no=228">국내 상장 중국기업</a></td>
(생략)
<td class="col_type1"><a href="/sise/sise_group_detail.naver?type=theme&no=374">4대강 복원</a></td>
<td class="col_type1"><a href="/sise/sise_group_detail.naver?type=theme&no=237">GTX(수도권 광역급행철도)</a></td>
내가 필요한 것은 테마명과 테마 넘버이다.
나머지를 더 효율적으로 없앨 함수를 bs4에서 지원할 것 같은데 못 찾아서 아래와 같이 스트링처리 했다.
name = []
num = []
for i in theme_name_s:
front = 'amp;no='
#i to string
a = str(i)
#front에서부터 4자리 추출
theme_num = str(a[a.find(front)+len(front):a.find(front)+len(front)+4])
#4자리에서 숫자가 아닌 것 제거
theme_num = re.sub(r'[^0-9]', '', theme_num)
front = 'no=' + str(theme_num) + '">'
end = '</a>'
theme_name = str(a[a.find(front)+len(front):a.find(end)])
#print(theme_num)
num.append(theme_num)
name.append(theme_name)
이것도 좀 이쁘게 하고 싶은데 코드가 추접스럽다.
theme_name_s의 자료형은 bs4.element.Tag 인데 이를 string으로 바꾸고,
테마 넘버를 찾기 위해 ‘amp;no=’라는 문자를 찾아서 그 길이만큼 더한 뒤에 넘버는 1~4자리 숫자니까 4를 더한 뒤에 숫자가 아닌 것은 뺐다.
테마 네임은 ‘amp;no=237">’ 다음부터 ‘</a>’ 전까지의 문자이니 그렇게 했다.
설명하는 것조차 부끄럽다.
이 코드는 치명적인 결함도 있는데 [no=374">4대강 복원] 과 같이 테마 이름에 숫자가 들어가고, 넘버가 한자리 수라면 오류가 날 것이다.
다행히(?) 그런 경우는 없었고 난 이렇게 처리했고 그 결과이다.
# print(name)
['해운', '유리 기판', '2024 상반기 신규상장', 'NI(네트워크통합)', '국내 상장 중국기업', '홈쇼핑', '케이블TV SO/MSO', '종합 물류', '원격진료/비대면진료(U-Healthcare)', '피팅(관이음쇠)/밸브', '제4이동통신', '의
료AI', '인터넷 대표주', '환율하락 수혜', '조선', '건설 대표주', '면세점', '윤활유', '미용기기', 'LNG(액화천연가스)', '4대강 복원', '재택근무/스마트워크', '마이데이터', '마이크로 LED', '모듈러주택', '조선기자
재', '수자원(양적/질적 개선)', '코로나19(음압병실/음압구급차)', '보안주(정보)', '도시가스', '주류업(주정, 에탄올 등)', '시멘트/레미콘', '쿠팡(coupang)', '네옴시티', 'GTX(수도권 광역급행철도)', '해저터널(지하
화/지하도로 등)', '기업인수목적회사(SPAC)', '아프리카 돼지열병(ASF)', '보톡스(보툴리눔톡신)', '엔터테인먼트']
# print(num)
['36', '557', '549', '56', '228', '38', '70', '141', '520', '49', '292', '149', '380', '30', '31', '374', '527',
'94', '543', '154', '507', '435', '452', '390', '513', '524', '213', '184', '86', '176', '381', '55', '310',
'417', '519', '237', '363', '322', '44', '284']
8페이지까지 전체를 크롤링하는 코드는 아래와 같다.
import re
import requests
from bs4 import BeautifulSoup as bs
import time
url = "<https://finance.naver.com/sise/theme.naver>"
page_url = "<https://finance.naver.com/sise/theme.naver?&page=>"
num = []
urls = []
name = []
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)
time.sleep(1)
print(j, ": done")
print("--------------------------------")
j를 이용하여 page만 바꿔주었고 한 페이지 조회가 끝날 때마다 done을 출력하였다.
**sleep에 대한 설명
time.sleep()
import time을 활용하여 time.sleep(1)을 추가하였다.
1초 동안 코드의 진행을 멈추고 쉬는 코드이다.
반복문을 통해서 너무 빠르게 반복해서 서버를 호출하면 트래픽 공격이 되어버릴 수도 있고,
더 중요한 것은 내 IP를 naver에서 차단해버릴 수도 있다.
request 수는 각 회사의 규정에 따라 다르다.
OpendartReader는 분당 1천회를 기준으로 하고,
네이버는 일일 25,000회라고 한다고 하는데 옛날 기준이라 지금은 다를 수 있다.
나는 단지 8개의 페이지를 조회할 뿐이지만 1초의 텀을 두었다.
다음 코드에서는 280개의 페이지를 조회할 것이기 때문에 반드시 sleep을 걸어서 서버를 배려해야한다.
'파이썬' 카테고리의 다른 글
[외전] 네이버증권 테마종목 크롤링 (4) 엑셀 다루기 (0) | 2024.04.06 |
---|---|
[파이썬] 네이버증권 테마종목 크롤링 (3) List → DataFrame → Excel (0) | 2024.04.06 |
[파이썬] 네이버증권 테마종목 크롤링 (2-2) beautifulsoup4 크롤링 (0) | 2024.04.06 |
[파이썬] 네이버증권 테마종목 크롤링 (1) url 분석 및 html 구조 파악 (0) | 2024.04.06 |
[파이썬] 네이버증권 테마종목 크롤링 (0) 업로드 계기 및 잡설 (1) | 2024.04.06 |