본문 바로가기
Python/Crawlling

[파이썬, Python] 크롤링(Crawlling)의 정의 & 크롤링 실습하기!

by coding-choonsik 2023. 9. 4.
728x90
반응형
SMALL

1. 크롤링과 스크래이핑

  • 크롤링(Crawling): 인터넷의 데이터를 활용하기 위해 정보들을 분석하고 활용할 수 있도록 수집하는 행위
  • 스크래이핑(Scraping): 크롤링 + 데이터를 추출해서 가공하는 최종 목표

 

2. 크롤링 실습

2-1. Basic English Speaking

 

(75 Audio Lessons) Daily English Conversation Practice | Questions and Answers By Topics

Daily English Conversation Practice - Questions and Answers by TopicYou have troubles making real English conversations? You want to improve your Spoken English quickly? You are too busy to join in any English speaking course?Don’t worry. Let us help you

basicenglishspeaking.com

 

▲ 위 페이지에서 제공하는 topics를 크롤링해보자.

 

import requests  # 원격지에 요청과 응답을 하는 라이브러리
from bs4 import BeautifulSoup

site = 'https://basicenglishspeaking.com/daily-english-conversation-topics/'
request = requests.get(site)  # get방식으로 url 접속 -> 응답코드를 반환
print(request)   

>>> <Response [200]>

 

 

# soup 객체
soup = BeautifulSoup(request.text)   # html을 파싱할 수 있게 해줌

# find(): 단일 태그 하나만 가져옴
divs = soup.find('div', {'class': 'thrv-columns'})   # 태그는 div이면서 class가 'thrv-columns'인 구간 가져오기
links = divs.findAll('a')  # divs에서 a태그 모두를 가져와 리스트로 반환

for link in links:
  print(link.text)  # 태그말고 글자만 봄

 

subject = []  # 토픽들을 담을 리스트
for link in links:
  subject.append(link.text)  # 빈 리스트에 텍스트만 어펜드시킴
len(subject)
>>> 75

 

print('총 ', len(subject), '개의 주제를 찾았습니다')
for i in range(len(subject)):
  print('{0:2d}. {1:s}'.format(i+1, subject[i]))   # format: {0번째 2자리 정수}, {1번째 문자열}

 

 


2-2. 다음 뉴스 기사 크롤링

 

# 뉴스 id를 넣으면 제목을 추출해주는 함수 만들기
def daum_news_title(news_id):
  url =  'https://v.daum.net/v/{}'.format(news_id)
  request = requests.get(url) 
  soup = BeautifulSoup(request.text)
  title = soup.find('h3', {'class','tit_view'})
  if title:
    return title.text.strip()   # title객체가 있으면 title의 text부분을 좌우 공백 없이 가져오기
  else:
    return '제목없음'

 

daum_news_title('20230601090853242')
>>> 하이브, JTBC 손잡고 新걸그룹 서바이벌 론칭…30일 첫방
daum_news_title('20230601071930573')
>>> '범죄도시3', 정식 개봉 첫날 누적 100만 거뜬 돌파…하루 74만 관객몰이 [Nbox]

 


2-3. 벅스 뮤직 차트 크롤링

 

나를 위한 플리, 벅스

나를 위한 플리, 벅스! 마음을 담은 노래추천 플레이리스트, 그리고 일상을 감성으로 가득 채워줄 essential player까지

music.bugs.co.kr

 

request = requests.get('https://music.bugs.co.kr/chart')
soup = BeautifulSoup(request.text)

titles = soup.findAll('p',{'class': 'title'})
# print(titles)

artists = soup.findAll('p',{'class':'artist'})
# print(artists)

 

 

for i in range(len(titles)):
  title = titles[i].text.strip()
  artist = artists[i].text.strip().split('\n')[0]  # 크리스토퍼와 같이 다음줄로 넘어가서 이상하게 나오는 부분을 해결 -> \n(다음줄로 넘김)으로 split하여 [0]번째만 씀
  print('{0:3d}위 {1} - {2}'.format(i+1, artist, title))

 

✅  위 코드를 zip함수를 이용하여 작성하기

for i, (title, artist) in enumerate(zip(titles, artists)):   # enumerate(): 인덱스도 반환  / # zip(): 이터레이터블 한 객체 중 길이가 짧은 길이만큼
    title = title.text.strip()
    artist = artist.text.strip().split('\n')[0]
    print('{0:3d}위 {1} - {2}'.format(i+1, artist, title))

 


2-4. 멜론 차트 크롤링

 

Melon

음악이 필요한 순간, 멜론

www.melon.com

 

  • 브라우저를 통해서 접속-> header에 브라우저 정보 등을 포함에서 get 방식으로 보냄(header가 있음!)
  • 파이썬 라이브러리를 통해 접속 -> header가 없음 -> 멜론에서 차단!
request = requests.get('https://www.melon.com/chart/index.htm')  
# print(request)  # <Response [406]>: 접속이 불가! 일반 사용자가 아닌 경우 접속하지 못하도록 막아놈
  • User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
  • header에 User-Agent 정보 넣어주기
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
request = requests.get('https://www.melon.com/chart/index.htm', headers=header)  # header에 정보를 포함하여 get방식으로 url을 가져옴  
print(request)  
>>> <Response [200]>

 

 

soup = BeautifulSoup(request.text)

titles = soup.findAll('div',{'class': 'rank01'})
artists = soup.findAll('span',{'class': 'checkEllipsis'})    #'div',{'class': 'rank01'}로 하면 안에 span태그가 있고 span태그의 text까지 같이 나와서 두번 중복으로 나옴!

for i, (title, artist) in enumerate(zip(titles, artists)):   # enumerate(): 인덱스도 반환  / # zip(): 이터레이터블 한 객체 중 길이가 짧은 길이만큼
    title = title.text.strip()
    artist = artist.text.strip()
    print('{0:3d}위 {1} - {2}'.format(i+1, artist, title))

 


2-5. 네이버 주식 크롤링

 

네이버페이 증권

국내 해외 증시 지수, 시장지표, 뉴스, 증권사 리서치 등 제공

finance.naver.com

# https://finance.naver.com/item/main.naver?code=005930
site = 'https://finance.naver.com/item/main.naver?code=005930'
request = requests.get(site)
print(request)
>>>  <Response [200]>

 

soup = BeautifulSoup(request.text)

div_today = soup.find('div',{'class':'today'})
print(div_today)

 

em = div_today.find('em')
print(em)  # 첫번째 em 태그만 찾음

 

price = em.find('span',{'class':'blind'}).text
print(price)
>>> 70,900

 

✅'삼성전자'와 종목코드 뽑기

div_company = soup.find('div',{'class':'wrap_company'})
# print(div_company)
name = div_company.find('h2').text
code = soup.find('span',{'class':'code'}).text
print('이름: {0}, 종목코드: {1}'.format(name, code))

>>> 이름: 삼성전자, 종목코드: 005930

 

✅ 다른 방식으로 종목코드 뽑기

div_company = soup.find('div',{'class':'wrap_company'})
# print(div_company)
name = div_company.a.text   # 첫번째 a태그의 text
print(name)
>>> 삼성전자

div_description = div_company.find('div', {'class': 'description'})
# print(div_description)
code = div_description.span.text    # 첫번째 span 태그의 text
print(code)
>>> 005930


# 거래량 뽑아오기
table_no_info = soup.find('table', {'class':'no_info'})
# print(table_no_info)
tds = table_no_info.find_all('td')
# print(tds)  # td들의 리스트
volume = tds[2].find('span',{'class':'blind'}).text
print(volume)
>>> 14,546,319


dic = {'price': price, 'name':name, 'code':code, 'volume':volume}
print(dic)

 

 

# 종목코드를 넣으면 위 딕셔너리 형태로 return 시키는 함수
def naver_finance(code):
  site = f'https://finance.naver.com/item/main.naver?code={code}'
  request = requests.get(site)
  soup = BeautifulSoup(request.text)
  div_today = soup.find('div',{'class':'today'})
  em = div_today.find('em')
  price = em.find('span',{'class':'blind'}).text  # 가격

  div_company = soup.find('div',{'class':'wrap_company'})
  name = div_company.a.text   # 회사명
  div_description = div_company.find('div', {'class': 'description'})
  code = div_description.span.text      # 업종코드

  table_no_info = soup.find('table', {'class':'no_info'})
  tds = table_no_info.find_all('td')
  volume = tds[2].find('span',{'class':'blind'}).text  # 거래량

  dic = {'price': price, 'name':name, 'code':code, 'volume':volume}
  return dic
  
naver_finance('000660')
>>> {'price': '110,300', 'name': 'SK하이닉스', 'code': '000660', 'volume': '5,513,206'}

 

✅ 여러 종목 코드로 정보 모아보기

codes = ['000660', '263750', '005950', '035900', '035720', '035420']

data = []

for code in codes:
  dic = naver_finance(code)
  data.append(dic)

print(data)
>>> [{'price': '110,300', 'name': 'SK하이닉스', 'code': '000660', 'volume': '5,513,206'}, {'price': '49,350', 'name': '펄어비스', 'code': '263750', 'volume': '583,047'}, {'price': '30,800', 'name': '이수화학', 'code': '005950', 'volume': '18,092,341'}, {'price': '127,300', 'name': 'JYP Ent.', 'code': '035900', 'volume': '774,046'}, {'price': '56,100', 'name': '카카오', 'code': '035720', 'volume': '999,188'}, {'price': '204,000', 'name': 'NAVER', 'code': '035420', 'volume': '544,232'}]


import pandas as pd
df = pd.DataFrame(data)
df

 

# 엑셀로 저장
df.to_excel('naver_finande.xlsx')

 

 

728x90
반응형
LIST