본문 바로가기
개발 Tools/파이썬_Webcrawling

webcrawling (웹크롤링) 네이버 기사 (시간, 타이틀, 링크) 크롤링 ( find, find_all, attrs, a["href"])

by 전컴반 2021. 7. 13.
반응형

이번엔 여러 회사의 최신 뉴스를 검색해서 링크를 적는 일이 주어졌다

그래서 간단히 크롤링을 이용하여 만들어보았다. (첫 페이지만 끌어온다) 

 

라이브러리 

 

먼저 필요한 라이브러리를 불러온다

 

import requests
from bs4 import BeautifulSoup

 

2개의 라이브러리 밖에 사용하지 않는다.

 

뉴스에 검색할 키워드 리스트에 담기

 

네이버 뉴스의 검색했을 때 url을 먼저 보겠다

url = https://search.naver.com/search.naver?query={검색 키워드}&where=news&ie=utf8&sm=nws_hty

이런 식으로 돼 있다. query="검색 키워드" 라 반복문을 사용하여 여러 검색 키워드를 볼까 한다.

 

이번에는 ["삼성", "sk하이닉스", "토스", "카카오", "KT", "KB국민은행" ] 이 정도의 회사로 해보겠다.

 

firms = ["삼성", "sk하이닉스", "토스", "카카오", "KT", "KB국민은행"]

 

BeautifulSoup 만들기

 

주소를 가져와서 soup 객체를 만들어 보겠다.

 

url = f"https://search.naver.com/search.naver?query={firm}&where=news&ie=utf8&sm=nws_hty"
res = requests.get(url)
res.raise_for_status()

soup = BeautifulSoup(res.text, "lxml")

내가 원하는 뉴스타이틀의 HTML 코드의 class 명은 news_tit이다. 그리고 날짜의 class 명은 info이다.

 

타이틀 날짜 가져오기

 

바로 가져와보겠다.

 

soup_tit = soup.find_all("a", attrs={"class": "news_tit"})
soup_info = soup.find_all("span", attrs={"class": "info"})

 

보면 "a" , "span" 태그에 정보가 있다. 우린 find_all을 하면 "a" 태그 중에 class 명이 news_tit 인 모든 애들을 가져온다

즉, 하나하나의 정보를 얻기 위해선 반복문을 통해 분리해줘야 한다.

 

각각의 정보 분리 & 링크 가져오기

 

근데 불러올 때, 키워드가 뉴스 타이틀에 있을 때만 불러온다고 하자. 의미 없는 기사도 뜨기 때문이다. 

zip이라는 함수를 써서 타이틀과 날짜를 동시에 분리한다.

 

링크는 a ["href"]를 사용하여 가져올 수 있다. 여러 개의 a 태그가 있을 땐 사용할 수 없음을 주의하자

 

코드를 보겠다.

 

    for tit, info in zip(soup_tit, soup_info):
        if firm in tit.get_text():
            print(f"{info.get_text()} {tit.get_text()} {tit['href']}")

 

이렇게 불러올 수 있다.

 

전체 코드와 출력

 

import requests
from bs4 import BeautifulSoup

firms = ["삼성", "sk하이닉스", "토스", "카카오", "KT", "KB국민은행"]

for firm in firms:
    url = f"https://search.naver.com/search.naver?query={firm}&where=news&ie=utf8&sm=nws_hty"
    res = requests.get(url)
    res.raise_for_status()

    soup = BeautifulSoup(res.text, "lxml")
    soup_tit = soup.find_all("a", attrs={"class": "news_tit"})
    soup_info = soup.find_all("span", attrs={"class": "info"})
    print(f"{firm} 기사")
    for tit, info in zip(soup_tit, soup_info):
        if firm in tit.get_text():
            print(f"{info.get_text()} {tit.get_text()} {tit['href']}")
    print("")
    
    
출력
삼성 기사
3시간 전 1위 소니 잡는다…삼성 이미지센서, 글로벌 완성차에 탑재 ht.hankyung.com/ec02107136384i
3시간 전 '승부 조작' 혐의 윤성환 전 삼성 투수, 첫 재판서 "공소사실 인정" http://www.ne
3시간 전 삼성전자, 비스포크 무풍에어컨 ‘미키 에디션’ 출시 https://www.e.co.kr/news/vie/2043914
1일 전 삼성전자, '제5회 삼성보안기술포럼' 참가 접수 http://news.o.kr/read/eco74410.htm
24면 1단 삼성물산, 건설현장 안전관리 투자 늘린다 http://www.fnnews.com/news/20210712120098092
20시간 전 SK하이닉스 '4세대 D램' 세계 첫 양산…삼성전자·마이크론과 3파전 h/news.mk.cad.php?n
A17면 TOP 삼성의 OTT 진출 서막?…TV플러스, 삼성TV·폰 없이 누구나 본다 httpschos201&pID=10200
1일 전 삼성전자 비스포크 무풍에어컨 '미키 에디션' 출시 http://yna.kr/AKR2021071500003?did=1195m
19시간 전 삼성전자, 사각지대 최소화하는 차량용 이미지센서 출시 https://daily.hank/lge/ittech/202

 

 

이런식으로 나온다는 것만 보여주기 위해 링크와 각각의 회사는 너무 길어 일정 부분 지웠다.

 

근데 보면 시간이 나오는 부분에서 "24면 1단" 이런 식으로 나온다. 이건 시간 태그 앞에 있는 태그라 그렇다. 정확하게 하고 싶다면 다시 태그를 찾아보면 된다. 조건문을 사용해서 해도 될 거 같다.

 

이상으로 마친다

반응형

댓글