ASAC 빅데이터 분석가 7기/ASAC 일일 기록
ASAC 빅데이터 분석가 과정 14일차 - 2 (24.12.23)
junslee
2024. 12. 23. 14:10
09_daum_site
- 웹에 있는 데이터를 수집을 하고 싶을 때
1) api : best
2) 일반적인 사이트
2-1) DART : 숨겨진 주소 잘 찾기 / 속도, ip로 방해받을 수 있음 (방어 전략)
2-2) daum --> 금융 : 숨겨진 주소를 찾을 필요 X
웹브라우저에서는 동작하지만 코드상에서 안될 때
- user-agent : 접속하는 sw의 정보
- referer : 해당 주소를 누가 호출
etc cookies - 웹드라이버 : 직접 브라우저 컨트롤 하는 방법
- 패키지 --> 셀레니움
- 속도가 느리다
- 로그인을 하기 싫다
(셀레니움으로 로그인 => 빠르게 접속) - 결론 : 정해진 것은 없다 => 해야 하는 사이트에 맞춰서 해야 한다
import urllib.request
url = "https://finance.daum.net"
res = urllib.request.urlopen(url)
res.read().decode("utf-8")
# 종종 403 에러가 나타날 수 있음!!
# => 정보가 들어오기는 하는데 원하는 정보가 아니라는 뜻
# 출력 생략
- https://finance.daum.net/api/search/ranks?limit=10
==> 브라우저 상에서는 정상적으로 보
url = "https://finance.daum.net/api/search/ranks?limit=10"
res = urllib.request.urlopen(url)
res.read().decode("utf-8")
- 403에러가 나타나거나, 접근 권한이 없다고 할 때
=> 나는 브러우저입니다
+ referer : 포털에서 직접 호출
url = "https://finance.daum.net/api/search/ranks?limit=10"
req = urllib.request.Request(
url,
data = None,
headers = {
"referer": "https://finance.daum.net/",
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"
}
)
# 브라우저가 실제 요청했던 실질적인 요청 양식&정보들을 채워서 보내기
res = urllib.request.urlopen( req).read().decode("utf-8")
res
# 출력 생략
- requests 패키지에서
=> 변환이나 이런 샘플 url 제공을 requests
import requests
url = "https://finance.daum.net/api/search/ranks?limit=10"
headers = {
"referer": "https://finance.daum.net/",
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"
}
# 요청 파라미터 : params --> 개발자도구(페이로드)
res = requests.get( url, headers=headers)
temp = res.text
temp
# 출력 생략
temp = res.json()
temp
# 출력 생략
- rank하고, 종목 이름, 현재 가격을 출력해보세요!!!!
for i in temp["data"]:
print(i["rank"], i["name"], i["tradePrice"])
print("*"*50)
1 삼성전자 53800
**************************************************
2 한미반도체 87800
**************************************************
3 셀트리온 193700
**************************************************
4 한화오션 35850
**************************************************
5 고려아연 1078000
**************************************************
6 SK하이닉스 171100
**************************************************
7 더본코리아 34500
**************************************************
8 기아 101000
**************************************************
9 카카오 39700
**************************************************
10 NAVER 201000
**************************************************
- 403 에러 처리 하는 부분 :업종 상위
url = "https://finance.daum.net/api/sector/wics?perPage=5&order=desc"
headers = {
"referer": "https://finance.daum.net/",
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"
}
# 요청 파라미터 : params -> 개발자도구(페이로드)
res = requests.get( url, headers=headers)
temp = res.text
temp
# 출력 생략
- 정리)
직접 찾아서 해보고, 처리하는 것 이외에는 답이 없다
그냥 해보자
난도가 높은 친구들이 있으니 고민을 해야 한다
10_selenium_localPC
- pip install ~~ : 일반적인 파이썬 패키지 설치 (주피터 노트북에서는 !필요)
- conda install ~~ : 아나콘다 이반으로 파이썬 패키지 설치
=> conda에서 있으면, 이것으로
=> 안되면 pip install ~~로 설치하기 - 아나콘다 프롬포트는 관리자 권한 실행 => 팅김 방지
- slelnium 패키지 설치
=> google : selenium anaconda, selenium install
=> 설치 : conda install ~~, pip install ~~ - 크롬 브라우저 설치
- 크롬 브라우저 컨트롤 할 webdriver
ref : https://sites.google.com/chromium.org/driver/getting-started
Chrome for Testing availability
chrome-headless-shellmac-arm64https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.204/mac-arm64/chrome-headless-shell-mac-arm64.zip200
googlechromelabs.github.io
ref : https://googlechromelabs.github.io/chrome-for-testing/
ChromeDriver - WebDriver for Chrome - Getting started
This page documents how to start using ChromeDriver for testing your website on desktop (Windows/Mac/Linux). You can also read Getting Started with Android or Getting Started with ChromeOS Setup ChromeDriver is a separate executable that Selenium WebDriver
sites.google.com
- 본인 브라우저의 버전이랑 chroemdirver의 버전을 체크하자
- 해당하는 본인 환경에 맞는 driver 다운 받기
- 압축 명확하게 풀어야 한다
- 편한 위치에 chromedrvier.exe 파일을 두고, 경로를 체크하자
- 다운 받은 choromedrvier.exe 의 경로를 지정을 해야 한다
path = r"C:\Users\kwonm\Downloads\chromedriver-win64\chromedriver.exe"
- 개인별로 본인 환경에 맞는 경로 지정을 해야 한다
- 다운 받을 때 버전 체크
압축을 풀고, 해제한 경로를 full 작성하는 것+ 파일명+ 확장자 - 정규식 문자열로 한 이유 : \\ 윈도우에서 개발 경로 붙이기 귀찮아서
- 접속에 필요한 모듈
from selenium import webdriver
from seleniuhttp://m.webdriver.chrome.service import Service
# chrome을 한 이유 : 크롬 브라우저를 통해서, 크롬 wedriver로 조절
- 필요한 정보들을 접근을 하는게 목적 : By. 찾을 요소!!!!! ==> 셀레니움 4.X
- By.~~~ : 필요한 정보들이 있는 요소를 중심으로 접근!!!!
from seleniuhttp://m.webdriver.common.by import By
- opt) 키보드로 뭔가 조작을 해야한다거나 마우스로 뭔가할 때
from seleniuhttp://m.webdriver.common.keys import Keys
- 참고: 셀레니움4에서는 기존과 다른게 접속을 한다
s = Service( path )
# 컨트롤 하려고하는 브라우저에 대한 변수화: driver
driver = webdriver.Chrome( service= s)
# 내가 웹브라우저에서 하는 모든 행동들을 코드로 제어할 수 있다
# 자세한 것은 메뉴얼 참조
driver.set_window_size(1000,1000)
# 내가 가려는 주소에
url = "https://naver.com"
driver.get(url)
# print(driver.page_source)
# 네이버 검색 창에 원하는 검색어를 입력하고 싶다
# 검색창의 검색어는
query_txt = "bts"
# 네이버 창의 어디에 이 검색어를 입력할지 지정
# 위치/요소 : xpath
# 규칙이 안 잡히면 : full_xpath, css, js, // tag + 속성들
element = driver.find_element( By.XPATH, '//*[@id="query"]')
element.send_keys( query_txt )
# 검색어 창에 btx라고 입력이 될 것이다
# 그 검색어로 조회를 하고자 하는 버튼 클릭
driver.find_element(By.XPATH, '//*[@id="search-btn"]').click()
# 참고) 화면 캡처
driver.save_screenshot("test_bts.png")
# 자동으로 브라우저 창 종료
driver.quit()
11_selenium_dart_re
from selenium import webdriver
from seleniuhttp://m.webdriver.chrome.service import Service
from seleniuhttp://m.webdriver.common.by import By
from seleniuhttp://m.webdriver.common.keys import Keys
import re
import time # 무조건 사용할 예정 : 셀레니움에서는 정보가 헛 돌 수 있다
import datetime # 파이썬에서 날짜, 시간 관련된 부분을 처리해주는 패키지 중 하나.
- 요청 날짜 :2024.12.17
date_year = 2024
date_month = 12
date_day = 17
page = 1
- 주소상 원하는 날짜에 대한 양식 YYYY.MM.DD
date = datetime.datetime( date_year, date_month,date_day)
date_YYYYMMDD = date.strftime("%Y.%m.%d") # 패키지에 대한 메뉴얼 참조 : 4자리 년도 %Y, %m
date_YYYYMMDD
url = f"https://dart.fss.or.kr/dsac001/mainAll.do?selectDate={date_YYYYMMDD}¤tPage={page}"
url
- 셀레니움으로 접속을 해보자
path = r"C:\Users\kwonm\Downloads\chromedriver-win64\chromedriver.exe"
s = Service( path )
driver = webdriver.Chrome( service= s)
driver.get(url)
- 참고) 지금 상황에서 driver 변수 안에 2024.12.17일 1페이지 모든 공시 정보가 있다
# driver.page_source : html -> 빠르게 정보 처리하기 위해서는 bs4
# BeautifulSoup( driver.page_source, "html.parser")
- Q) 1번 공시의 시간에 대한 정보를 접근하고 출력해보자
//*[@id="listContents"]/div[2]/table/tbody/tr[1]/td[1]
/html/body/div[4]/div[2]/div[1]/div[2]/div[3]/div[2]/table/tbody/tr[1]/td[1]
# xpath에서 규칙이 보인다
# xpath로 정보를 접근해보자
b_path = '//*[@id="listContents"]/div[2]/table/tbody/tr[1]/td[1]'
temp = driver.find_element(By.XPATH, b_path)
temp.text
- Q) 간단하게 공시 시간에 대한 정보만 앞의 5개 공시들에 대해서 출력해보자
=> for : 위에서 찾은 공시 시간에 대한 부분에 접근 방식이 규칙화가 가능한지 체크
# //*[@id="listContents"]/div[2]/table/tbody/tr[1]/td[1]
for i in range(1, 6):
b_path = f'//*[@id="listContents"]/div[2]/table/tbody/tr[{i}]/td[1]'
temp = driver.find_element(By.XPATH, b_path)
print(temp.text)
- Q) 1번 회사의 이름
co_path = '//*[@id="listContents"]/div[2]/table/tbody/tr[1]/td[2]/span/a'
temp = driver.find_element(By.XPATH, co_path)
temp.text
temp.get_attribute("href")
re.findall(r"\d{8}",temp.get_attribute("href") )[0]
- Q) 1번 공시에 대한 이름을 출력해보자
- xpath : //*[@id="r_20241217900785"]
=> 모든 공시에 대한 고유값을 알아야 한다 - xpath 접근은 가능하지만 규칙화를 하는데 있어서는 불편하다
full_xpath : /html/body/div[4]/div[2]/div[1]/div[2]/div[3]/div[2]/table/tbody/tr[1]/td[3]/a
=> 조금 더 규칙화에 용이하다
r_path = '/html/body/div[4]/div[2]/div[1]/div[2]/div[3]/div[2]/table/tbody/tr[1]/td[3]/a'
temp = driver.find_element(By.XPATH, r_path)
temp.text
- Q) 1번 공시에 대한 rcpno를 찾아보자
r_path = '/html/body/div[4]/div[2]/div[1]/div[2]/div[3]/div[2]/table/tbody/tr[1]/td[3]/a'
temp = driver.find_element(By.XPATH, r_path).get_attribute("href")
re.findall(r"\d{14}", temp)[0]
- 기존 tag 중심으로 찾을려면
driver.find_elements(By.TAG_NAME, "tr")[1].text
btn_path = '//*[@id="listContents"]/div[3]/div[2]/ul/li[2]/a'
driver.find_element(By.XPATH, btn_path).click()
time.sleep(3) # 3초 정도 대기하는 코드 -> 꼭 해야지만 정보가 들어올 때 발생한다
# 해당 사이트에서 나를 차단할 수 있어서 시간 지연을 줘야 한다 (실험필요)
len( driver.find_elements(By.TAG_NAME,"tr")) # ---> 갯수가 이상하게 들어올 때
# -> 101개 들어와야 하는데 적게 들어온다
# => driver 변수안에 정보가 충분히 안 담겨서 발생하는 현상
- 정리
- 일반적인 웹 사이트 : 개발자 도구 -> 네트워크 쪽 찾아보기!!
+ 헤더에 user-agent, refere etc
+ 웹브라이저를 통한 셀레니움 (브라우저 + 브라우저 버전에 맞는 webdriver) + bs4
결론 : 본인이 수집해야하는 사이트에 맞춰서 해야한다 (그때그때 다르다)
크롤링 : 어려운 부분 없다, 귀찮음은 있다, 찾아보고 실험도 해야 해서
=> 몇 번 해보면 감을 잡을 것