728x90
반응형
SMALL
1. 크롤링과 스크래이핑
- 크롤링(Crawling): 인터넷의 데이터를 활용하기 위해 정보들을 분석하고 활용할 수 있도록 수집하는 행위
- 스크래이핑(Scraping): 크롤링 + 데이터를 추출해서 가공하는 최종 목표
2. 크롤링 실습
2-1. Basic English Speaking
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. 벅스 뮤직 차트 크롤링
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. 멜론 차트 크롤링
- https://www.melon.com/chart/index.htm
- robots.txt: 웹사이트에 크롤러같은 로봇들의 접근을 제어하기 위한 규약, 권고안이라 꼭 지킬 의무는 없음
- https://www.melon.com/robots.txt
- 크롤링 할 수 있는 폴더들을 알 수 있음
- 브라우저를 통해서 접속-> 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. 네이버 주식 크롤링
# 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
'Python > Crawlling' 카테고리의 다른 글
[파이썬, Python] 이미지 크롤링 하기! (0) | 2023.09.05 |
---|---|
[파이썬, Python] 셀레니움으로 인스타그램 크롤링하기! (0) | 2023.09.05 |
[파이썬, Python] 셀레니움(Selenium) 라이브러리를 활용한 브라우저 컨트롤링 (0) | 2023.09.05 |