본문 바로가기
코딩 연습/코딩배우기

[Python] 파이썬 웹 크롤링 - 스크래핑 관련 연습 코드 [네이버 날씨 & 뉴스, 오늘의 영어지문 등 가져오기]

by good4me 2021. 6. 29.

goodthings4me.tistory.com

 

[출처] 파이썬 코딩 무료 강의 (활용편3) - 웹 크롤링? 웹 스크래핑! 제가 가진 모든 비법을 알려드리겠습니다. [나도코딩]  https://youtu.be/yQ20jZwDjTE

■ 웹 스크래핑을 이용하여 나만의 비서 만들기

오늘의 날씨, 헤드라인 뉴스 3개, IT뉴스 3건, 해커스 어학원 홈페이지에서 오늘의 영어 회화 지문 등 가져오기

from bs4 import BeautifulSoup
import requests
import re
from selenium import webdriver
import time

# BeautifulSoup 객체 만들기
def create_soup(url):
    headers = {
        'User-Agent': ('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        ' (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Edg/91.0.864.59')
    }    
    response = requests.get(url, headers=headers)
    response.raise_for_status()
    soup = BeautifulSoup(response.text, 'lxml')
    return soup


# Project) 웹 스크래핑을 이용하여 나만의 비서 만들기 
# - 오늘의 날씨, 헤드라인 뉴스 3개, IT뉴스 3건, 해커스 어학원 홈페이지에서 오늘의 영어 회화 지문을 가져온다
def scrape_weather():
    print('[[ 오늘의 날씨 ]]')
    url = 'https://search.naver.com/search.naver?where=nexearch&sm=top_sug.asiw&fbm=1&acr=1&acq=%EC%84%9C%EC%9A%B8+%EB%82%A0&qdt=0&ie=utf8&query=%EC%84%9C%EC%9A%B8+%EB%82%A0%EC%94%A8'
    soup = create_soup(url)
    
    # 흐림, 어제보다 00 높아요
    cast = soup.find('p', class_='cast_txt').get_text()
    # 현재 00도 (최저 / 최고)
    curr_temp = soup.find('p', class_='info_temperature').get_text().replace('도씨', '')
    min_temp = soup.find('span', class_='min').get_text()
    max_temp = soup.find('span', class_='max').get_text()
    # 오전/오후 강수확률
    morning_rain_rate = soup.find('span', class_='point_time morning').get_text().strip()
    afternoon_rain_rate = soup.find('span', class_='point_time afternoon').get_text().strip()
    
    # 미세먼지 정보 - dl > dd 태그 3개로 구성
    dust = soup.find('dl', attrs={'class':'indicator'})
    pm10 = dust.find_all('dd')[0].get_text()  # 미세먼지
    pm25 = dust.find_all('dd')[1].get_text()  # 초미세먼지
    
    # 출력
    print(cast)
    print(f'현재 {curr_temp} (최저 {min_temp} / 최고 {max_temp})')
    print(f'오전 {morning_rain_rate} / 오후 {afternoon_rain_rate}')
    print()
    print(f'미세먼지 {pm10}')
    print(f'초미세먼지 {pm25}')
    print()
    


def scrape_headline_news():
    print('[[ 헤드라인 뉴스 ]]')
    url = 'https://news.naver.com'
    soup = create_soup(url)   
    
    # find_all(, limit=)  limit으로 가져오는 리스트의 수를 제한
    news_list = soup.find('ul', attrs={'class':'hdline_article_list'}).find_all('li', limit=3)
    for index, news in enumerate(news_list, 1):
        title = news.find('a').get_text().strip()
        link = url + news.find('a')['href']
        print(f'{index}. {title}\n{link}\n')
    
    print()


def scrape_it_news():
    print('[[ IT 뉴스 ]]')
    url = 'https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=105'
    soup = create_soup(url)   
    
    news_list = soup.find('ul', attrs={'class':'cluster_list'}).find_all('li')
    for index, news in enumerate(news_list, 1):
        a_idx = 0
        # 기사 앞에 이미지 유무에 따라 가져올 a태그의 위치가 틀려짐(인덱스 필요)
        img = news.find('img')
        if img:
            a_idx = 1
        title_a = news.find_all('a')[a_idx]
        title = title_a.get_text().strip()
        link = url + title_a['href']
        print(f'{index}. {title}\n{link}\n')


def scrape_english():

    # 해커스 매일 영어회화 - iframe 구조임
    # <div class="cnt_area p_r">
    # <iframe id="ifm_content" src="https://www.hackers.co.kr/?c=s_lec/lec_study/lec_I_others_english&amp;padN=Y&amp;iframe=Y&amp;resize=N" \
    # height="2701px" frameborder="0" scrolling="no" class="talk_ten_area" onload="iframeLoaded();">
    
    print('[[ 오늘의 영어회화 ]]')    
    url = 'https://www.hackers.co.kr/?c=s_lec/lec_study/lec_I_others_english&padN=Y&iframe=Y&resize=N'
    soup = create_soup(url)         

    # div id='conv_kor_t?'와 같이 conv_kor_t로 시작하는 것을 찾아야 함 - re.compile() 사용
    sentences = soup.find_all('div', attrs={'id':re.compile('^conv_kor_t')})
    # print(len(sentences)) # 8
    
    # 한글, 영어 지문 순을 영어 먼저, 한글 지문이 뒤에 배치
    # 지문이 각 4개 총 8개라고 가정 시, index 4~7이 영어 지문
    print('\n영어 지문')
    for sentence in sentences[len(sentences)//2:]:  # 총 개수 // 2 부터 끝까지 슬라이싱
        print(sentence.get_text().strip())

    print('\n한글 지문')
    for sentence in sentences[:(len(sentences)//2)]:  # 총 개수 // 2 까지 슬라이싱
        print(sentence.get_text().strip())        
    
    ### selenium 으로 가져오기 ###
    options = webdriver.ChromeOptions()
    options.headless = True
    options.add_argument('window-size=1920x1080')
    options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36')
    
    browser = webdriver.Chrome('./chromedriver.exe', options=options)
    # browser.maximize_window()
    url = 'https://www.hackers.co.kr/?c=s_lec/lec_study/lec_I_others_english&padN=Y&iframe=Y&resize=N'
    browser.get(url)
    time.sleep(2)
    
    sentences = browser.find_elements_by_class_name('conv_sub')
    # print(len(sentences)) # 8
    
    print('\n영어 지문')
    for sentence in sentences[len(sentences)//2:]:  # 총 개수 // 2 부터 끝까지 슬라이싱
        print(sentence.text.strip())

    print('\n한글 지문')
    for sentence in sentences[:(len(sentences)//2)]:  # 총 개수 // 2 까지 슬라이싱
        print(sentence.text.strip())   
    

if __name__ == '__main__':
    scrape_weather()
    scrape_headline_news()
    scrape_it_news()
    scrape_english()
    

good4me.co.kr

[결과]

[[ 오늘의 날씨 ]]
흐림, 어제보다 1˚ 높아요
현재 25℃  (최저 21˚ / 최고 29˚)
오전 강수확률 20% / 오후 강수확률 60%

미세먼지 29㎍/㎥좋음
초미세먼지 18㎍/㎥보통

[[ 헤드라인 뉴스 ]]
1. '청산가치 더 높다' 조사보고서에…쌍용차 "근거 없어"
https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=101&oid=015&aid=0004569816

2. 정세균·이광재 '反이재명 연대' 꿈틀…파급력은 '물음표'
https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=100&oid=008&aid=0004608312

3. 삼성전자, 새로운 갤럭시 워치 사용자경험 '원 UI 워치' 공개
https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=105&oid=009&aid=0004816051


[[ IT 뉴스 ]]
1. 네이버 노조 "최인혁, 모든 계열사 대표직서 해임해야"…노사대책위도 요구
https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=105https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=105&oid=214&aid=0001132321

2. "2년이상 직장내 괴롭힘 방치"…네이버 노조 '동료 사망사건' 조사 결과발표
https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=105https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=105&oid=421&aid=0005441094

3. 네이버 노조 “가해자 비호 정황”…재발방지 대책위 꾸려야
https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=105https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=105&oid=056&aid=0011072179

4. 네이버 노조 "COO 즉각 해임·재발방지대책위 요구"
https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=105https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=105&oid=092&aid=0002226102

[[ 오늘의 영어회화 ]]

영어 지문
Heidi: So, do you love using your new desk?
Rob: Well, I love it because it really looks modern. The only problem is, it’s not as spacious as my old one.
Heidi: Well... less space, less paperwork!
Rob: If you say so...

한글 지문
Heidi: 그래서, 새 책상을 쓰니 좋아요?
Rob: 그럼요, 아주 최신식인 것 같아서 너무 좋아요. 유일한 문제점이라면, 전에 쓰던 책상만큼 넓지 않다는 점이에요.
Heidi: 흠... 자리가 좁다면 서류업무도 줄여야겠네요!
Rob: 그렇겠네요...

영어 지문
Heidi: So, do you love using your new desk?
Rob: Well, I love it because it really looks modern. The only problem is, it’s not as spacious as my old one.
Heidi: Well... less space, less paperwork!
Rob: If you say so...

한글 지문
Heidi: 그래서, 새 책상을 쓰니 좋아요?
Rob: 그럼요, 아주 최신식인 것 같아서 너무 좋아요. 유일한 문제점이라면, 전에 쓰던 책상만큼 넓지 않다는 점이에요.
Heidi: 흠... 자리가 좁다면 서류업무도 줄여야겠네요!
Rob: 그렇겠네요...

 

댓글