파이썬/파이썬 활용

파이썬 활용 08 - 1 - 웹 스크래핑 (CSV - 네이버 금융)

H-V 2021. 11. 5. 11:21

유투버 '나도코딩'님 강의 참조

 

*CSV란?

  • CSV(영어: comma-separated values)는 몇 가지 필드를 쉼표(,)로 구분한 텍스트 데이터 및 텍스트 파일이다. 확장자는 .csv이며 MIME 형식은 text/csv이다.

 

 

 

01 코스피 정보 들고 오기

여기서 코스피 순위를 한번 긁어와서 엑셀로 저장하는것을 배울 예정

 

  1. 똑같이 이 웹페이지도 url을 보면 페이지 형태로 정보가 변한다
    이 url을 들고 스크래핑을 해보자
  2. 스크래핑을 위한 기본 세팅
    import csv
    import requests
    from bs4 import BeautifulSoup
    
    url = "https://finance.naver.com/sise/sise_market_sum.nhn?sosok=0&page="
    
    for page in range(1, 5):
        res = requests.get(url + str(page))
        res.raise_for_status()
    
        soup = BeautifulSoup(res.text, "lxml")​
    1) page별로 정보가 다르니 url에서 페이지 숫자를 빼고 세팅
    2) 포문을 돌면서 페이지를 받아오면 되고 reqeust.get()으로 받는 정보는 url+번호 를 넘기면 됨

  3. 웹 페이지 분석
    이 웹페이지 구성은 약간 복잡하다. 테이블 형식이지만 내가 뽑고자 하는 데이터가 어디 속해있는지만 알면 스크래핑이 수월 하다. 
  4. 1차 데이터 들고 와 보기
    import csv
    import requests
    from bs4 import BeautifulSoup
    
    url = "https://finance.naver.com/sise/sise_market_sum.nhn?sosok=0&page="
    
    for page in range(1, 2):
        res = requests.get(url + str(page))
        res.raise_for_status()
    
        soup = BeautifulSoup(res.text, "lxml")
        
        data_rows = soup.find("table", attrs={"class":"type_2"}).find("tbody").find_all("tr")
    
        for row in data_rows:
            columns = row.find_all("td")
            data = [column.get_text() for column in columns]
            print(data)​
    1) 이미지 스크래핑과 비슷한 개념. 페이지에 따라 포문을 돌면서 정보를 들고 오게 됨
    2) 우리가 뽑고자하는 데이터가 table → tbody → tr 밑에 있다
    3) tr 밑에 다시 td 형태로 데이터가 뿌려져 있기때문에 tr을 일단 'data_rows'에 다 담는다.
    4) 다시 포문을 돌면서 'data_rows' 각각의 tr이 가진 td들을 다 들고 온다
    5) 다시 포문을 한번 더 돌면서 'columns'의 td가 가진 정보들을 data에 담는다.
  5. 필요없는 빈칸, 정보들
    빈칸부터 없애 보자. tr중 하나의 td만 가진 혹은 td가 없는 tr을 지우면 된다
  6. 삭제하기
    for page in range(1, 2):
        res = requests.get(url + str(page))
        res.raise_for_status()
    
        soup = BeautifulSoup(res.text, "lxml")
        
        data_rows = soup.find("table", attrs={"class":"type_2"}).find("tbody").find_all("tr")
    
        for row in data_rows:
            columns = row.find_all("td")
            if len(columns) <= 1:
                continue
            data = [column.get_text().strip() for column in columns]
            print(data)​

    1) tr중 td가 1나 혹은 그 이하인거는 스킵
    2) 스킵이 안된 데이터에 .strip()을 써서 빈칸 삭제

  7.  이제 이 데이터를 csv로 담기
    import csv
    import requests
    from bs4 import BeautifulSoup
    
    url = "https://finance.naver.com/sise/sise_market_sum.nhn?sosok=0&page="
    
    filename = "market capitalization 1~200 rank.csv"
                            #csv저장시 한글깨짐 방지
    f = open(filename, "w", encoding="utf-8-sig", newline="") #newline = 자동 줄바꿈을 공백으로
    writer = csv.writer(f)
    #.split("\t")으로 공백을 처리하면 리스트 형식으로 저장 됨
    title = "N	종목명	현재가	전일비	등락률	액면가	시가총액	상장주식수	외국인비율	거래량	PER	ROE".split("\t")
    writer.writerow(title)
    
    for page in range(1, 5):
        res = requests.get(url + str(page))
        res.raise_for_status()
    
        soup = BeautifulSoup(res.text, "lxml")
        
        data_rows = soup.find("table", attrs={"class":"type_2"}).find("tbody").find_all("tr")
    
        for row in data_rows:
            columns = row.find_all("td")
            if len(columns) <= 1:
                continue
            data = [column.get_text().strip() for column in columns] #이미 리스트 형식으로 받아옴
            # print(data)
            writer.writerow(data) #.writerow()는 반드시 리스트 형태로 넣어야 함



  8. 엑셀로 체크