[문제1] 네이버 날씨 정보 스크래핑
from bs4 import BeautifulSoup
import requests
import datetime
res = requests.get('https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=%EB%82%A0%EC%94%A8')
soup = BeautifulSoup(res.text, 'lxml')
# div 태그에서 한 단계 더 아래인 h2 태그로 이동 (현재 위치)
location = soup.find('div', attrs={'class':'title_area _area_panel'}).find('h2', attrs={'class':'title'}).text
# attrs 없어도 알아서 속성의 값으로 적용됨
weather = soup.find('span', {'class':'weather before_slash'}).text
# div 태그 아래에 있는 모든 텍스트 값을 가져옴 (현재온도 몇 도)
temperature = soup.find('div', {'class':'temperature_text'}).text
lowest = soup.find('span', {'class':'lowest'}).text # 최저기온
highest = soup.find('span', {'class':'highest'}).text # 최고기온
dust = soup.find('li', {'class':'item_today level2'}).text # 미세먼지
while True:
print('='*30)
print('날씨 확인 프로그램')
print('='*30)
print('접속 시간:', datetime.datetime.now())
print('접속 위치:', location)
print('-'*30)
print('1. 현재 날씨 및 온도 확인')
print('2. 최저/최고 온도 확인')
print('3. 미세먼지 확인')
print('0. 종료')
print('-'*30)
no = int(input('번호를 입력하세요:'))
if no == 0:
print('프로그램을 종료합니다.')
break
elif no ==1:
print('='*30)
print('현재 날씨 확인')
print('='*30)
print(weather, '/', temperature)
print('-'*30)
elif no ==2:
print('='*30)
print('최저/최고 기온 확인')
print('='*30)
print('최저 기온:', lowest[4:]) # 슬라이싱을 이용해 최저 기온의 숫자만 가져옴
print('최고 기온:', highest[4:])
print('-'*30)
elif no ==3:
print('='*30)
print('미세먼지 확인')
print('='*30)
print(dust[7:]) # 슬라이싱을 이용해 미세먼지의 정보만 가져옴
print('-'*30)
[문제2] 네이버에서 bts 이미지를 검색 한 후 나온 결과 중 10개의 이미지를 저장하기
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver import Chrome, ChromeOptions
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
import os
import requests
driver = Chrome(service=Service(ChromeDriverManager().install()), options=ChromeOptions())
driver.get('https://www.naver.com')
ele = driver.find_element(By.ID, 'query') # 검색 필드에 대한 element 객체를 가져옴
ele.send_keys('bts') # bts 입력
ele.send_keys(Keys.ENTER) # enter 클릭
driver.find_element(By.LINK_TEXT, '이미지').click() # 이미지 필드 클릭
time.sleep(5)
# 클릭 이벤트를 적용하려면 a 태그가 필요하기 때문의 a 태그의 CSS 선택자 값을 가져옴
bts_imgs = driver.find_elements(By.CSS_SELECTOR, '#main_pack > section.sc_new.sp_nimage._fe_image_viewer_prepend_target > div.api_subject_bx._fe_image_tab_list_root.ani_fadein > div > div > div.image_tile._fe_image_tab_grid > div > div > div > a')
print('그림 개수:', len(bts_imgs)) # 한 페이지에 50개
img_dir = './bts_img/' # 현재 경로 밑에 bts_img 폴더 생성
if not os.path.exists(img_dir): # 해당 디렉토리가 없으면
os.makedirs(img_dir) # 해당 디렉토리를 생성
print('폴더 생성')
else:
print('폴더가 이미 존재합니다.')
for i, img in enumerate(bts_imgs):
img.click() # 검색된 이미지의 a태그 클릭 (오른쪽에 큰 원본 이미지를 보여줌)
original_img = driver.find_element(By.CLASS_NAME, '_fe_image_viewer_image_fallback_target')
img_url = original_img.get_attribute('src') # 원본 이미지의 주소값을 가져옴
# 이미지 url이 요청할 수 없는 프로토콜로 시작하면 스킵
if not img_url.startswith('http'): continue
res = requests.get(img_url) # 해당 url로 다시 요청
with open(f'{img_dir}bts_{i:02d}.jpg', 'wb') as f: # 이미지는 bts_img 폴더 안에 저장이 됨
print(img_url) # 이미지 url을 하나씩 출력해줌
f.write(res.content)
if i >= 10: break
print('BTS 사진 저장 완료')
[문제3] 멜론 사이트 최신곡 검색
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver import Chrome, ChromeOptions
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = Chrome(service=Service(ChromeDriverManager().install()), options=ChromeOptions())
driver.get('https://www.melon.com/new/index.htm')
soup = BeautifulSoup(driver.page_source)
# 첫번째 tr 태그의 CSS 선택자로 검색
song_list = soup.select('#frm > div > table > tbody > tr') # n번째 child 속성 값을 지워줌
print(len(song_list)) # 음악 목록 50개
# formatted string에서 정렬 문자: ^(가운데), <(기본:왼쪽 정렬), >(오른쪽 정렬)
print(f'{"곡목":^30s}{"가수":^30s}{"앨범":^30s}') # 30개 글자의 공간을 확보
print('-'*90)
for rank, song in enumerate(song_list, 1): # enumerate(두번째 값)은 시작 값 : 1부터 시작
# class 속성의 값이 wrap_song_info인 태그가 2개여서(노래제목과 가수, 앨범명) find_all로 검색
song_info = song.find_all('div', {'class':'wrap_song_info'}) # 2개의 element가 들어있음
if rank > 10: break # 상위 10개만 출력 (1부터 시작하기 때문에 11에서 멈춤)
title = song_info[0].find('div', {'class':'ellipsis rank01'}).find('a').text # div 태그 밑에 있는 a태그 안에 있는 곡명을 가져옴
singer = song_info[0].find('div', {'class':'ellipsis rank02'}).find('a').text # div 태그 밑에 있는 a태그 안에 있는 가수이름을 가져옴
album = song_info[1].find('div', {'class':'ellipsis rank03'}).find('a').text # div 태그 밑에 있는 a태그 안에 있는 앨범명을 가져옴
print(f'{rank}.{title:<30s}|{singer:<30s}|{album:<30s}')
'데이터 분석 > 웹 스크래핑' 카테고리의 다른 글
[Web Scrapping 실습] Auto Crawler (0) | 2023.11.06 |
---|---|
[Web Scrapping 실습] Crawling Test (0) | 2023.11.03 |
[Web Scrapping] XPath (XML Path Language) (0) | 2023.11.01 |
[Web Scrapping 실습] Selenium (0) | 2023.11.01 |
[Web Scrapping 실습] BeautifulSoup (0) | 2023.11.01 |