[힙한취미코딩] 뉴스 스크래핑 with Python
#스파르타 #sparta #힙한취미코딩 #스크래핑 #크롤링 #기사크롤링 #네이버기사 #한이음
네이버에서 추석을 검색하고 나오는 뉴스들을 수집!
https://search.naver.com/search.naver?where=news&sm=tab_jum&query=추석
추석 : 네이버 뉴스검색
'추석'의 네이버 뉴스검색 결과입니다.
search.naver.com
from bs4 import BeautifulSoup
from selenium import webdriver
driver = webdriver.Chrome('chromedriver')
url = "https://search.naver.com/search.naver?where=news&sm=tab_jum&query=추석"
driver.get(url)
req = driver.page_source
soup = BeautifulSoup(req, 'html.parser')
이렇게까지 적었다면 추석을 검색해서 나온 뉴스 탭 페이지의 html 코드를 가져와 soup에 저장한 것이다.
여기서 다시 첫번째 기사의 제목을 가져오고 싶다면?
기사 우클릭->검사를 눌러서 elements의 selector를 복사해온다.
select_one에 무엇을 찾을지 붙여넣고 출력해보면 '추석 선물 의료기기 살 땐 '허가' 여부 꼭 확인' 이라는
기사 제목이 잘 나온 것을 확인할 수 있다.
뉴스목록 구조를 보면 ul 태그 안에 <li> list 태그로 뉴스들이 들어가있다.
이렇게 <li> 태그들을 select로 걸러내면 여러 개의 li 들을 한 번에 가져올 수 있다.
articles에는 리스트 형태로 여러 기사들이 들어가있지 때문에 for문으로 출력해본다.
articles = soup.select('#main_pack > section.sc_new.sp_nnews._prs_nws > div > div.group_news > ul > li')
그 중에 제목을 가져올 것이기 때문에 제목까지 도달할 수 있도록 태그를 select_one 해준다.
그런데 강의 촬영 시점과 지금 뉴스 구조는 조금 다른 것 같다... 그래서 내가 고쳐보았다.
강의 코드
for article in articles:
title = article.select_one('dl > dt > a')
print(title.text)
내 코드
언론사는 span 태그 안에 있었는데 잘 안가져와져서 나중에 다시 시도해봐야겠다.
for article in articles:
title = article.select_one(' div.news_wrap.api_ani_send > div > a')
url = article.select_one('div.news_wrap.api_ani_send > div > a')['href']
# comp = article.select_one('div.news_wrap.api_ani_send > div > div.news_info > div.info_group > a.info.press > span')
print(title.text)
print(url)
# print(comp.text)
특정 단어를 떼고 싶다면 이렇게 띄어쓰기 앞에 글자를 가져와라, 언론사를 없애라, 이렇게 문자열을 바꿀 수도 있다.
.split(' ')[0].replace('언론사', '')
엑셀에 저장하기
file > settings > python interpreter
openpyxl 을 다운받아준다.
openpyxl 이용해보기
이렇게 코드를 짜고 돌려보면 articles.xlsx 파일이 생긴 것을 확인할 수 있다.
from openpyxl import Workbook
wb = Workbook()
ws1 = wb.active
ws1.title = "articles"
ws1.append(["제목", "링크", "신문사"])
wb.save(filename='articles.xlsx')
뉴스에 대입하기!
from bs4 import BeautifulSoup
from selenium import webdriver
from openpyxl import Workbook
driver = webdriver.Chrome('chromedriver')
url = "https://search.naver.com/search.naver?where=news&sm=tab_jum&query=추석"
driver.get(url)
req = driver.page_source
soup = BeautifulSoup(req, 'html.parser')
articles = soup.select('#main_pack > section.sc_new.sp_nnews._prs_nws > div > div.group_news > ul > li')
wb = Workbook()
ws1 = wb.active
ws1.title = "articles"
ws1.append(["제목", "링크"])
# 선택한 elements의 태그까지 다 나옴
# print(articles)
for article in articles:
title = article.select_one(' div.news_wrap.api_ani_send > div > a')
url = article.select_one('div.news_wrap.api_ani_send > div > a')['href']
# comp = article.select_one('div.news_wrap.api_ani_send > div > div.news_info > div.info_group > a.info.press > span')
print(title.text)
print(url)
# print(comp.text)
ws1.append([title, url])
driver.quit()
wb.save(filename = 'articles.xlsx')
스택오버플로우의 도움을 받고자 했지만 잘 안돼서 잠깐 패스~~~~~
이메일 보내기
보내는 사람은 구글이메일 계정을 써야한다.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
# 보내는 사람 정보
me = "보내는사람@gmail.com"
my_password = "비밀번호"
# 로그인하기
s = smtplib.SMTP_SSL('smtp.gmail.com')
s.login(me, my_password)
# 받는 사람 정보
you = "받는사람@아무_도메인"
# 메일 기본 정보 설정
msg = MIMEMultipart('alternative')
msg['Subject'] = "제목"
msg['From'] = me
msg['To'] = you
# 메일 내용 쓰기
content = "메일 내용"
part2 = MIMEText(content, 'plain')
msg.attach(part2)
# 메일 보내고 서버 끄기
s.sendmail(me, you, msg.as_string())
s.quit()
이렇게 필요한 곳에 정보를 넣고서도 코드실행이 잘 되지 않는다.
gmail 보안에 따라서 여러 설정을 바꿔주어야한다.
2단계 인증 해제
https://myaccount.google.com/signinoptions/two-step-verification
로그인 - Google 계정
하나의 계정으로 모든 Google 서비스를 Google 계정으로 로그인
accounts.google.com
위 링크로 들어가서 2단계 인증을 사용 안 함 해주어야 한다.
https://myaccount.google.com/lesssecureapps
로그인 - Google 계정
하나의 계정으로 모든 Google 서비스를 Google 계정으로 로그인
accounts.google.com
보안 수준이 낮은 앱 허용하기!
이렇게 하고나면 아래 코드가 동작이 된다.
위 코드에서 한 사람에게 메일을 여러 개 보내는 기능과 첨부파일을 보내는 기능을 추가했다.
내가 가지고있는 articles.xlsx 파일이 추석기사.xlsx라는 이름으로 첨부된다.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
# 받는 사람들
emails = ['@naver.com', '@naver.com']
# 보내는 사람 정보
me = "@gmail.com"
my_password = ""
# 로그인하기
s = smtplib.SMTP_SSL('smtp.gmail.com')
s.login(me, my_password)
for you in emails:
# 받는 사람 정보
# you = "받는사람@아무_도메인"
# 메일 기본 정보 설정
msg = MIMEMultipart('alternative')
msg['Subject'] = "제목"
msg['From'] = me
msg['To'] = you
# 메일 내용 쓰기
content = "메일 내용"
part2 = MIMEText(content, 'plain')
msg.attach(part2)
# 첨부파일
part = MIMEBase('application', "octet-stream")
with open("articles.xlsx", 'rb') as file:
part.set_payload(file.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment", filename="추석기사.xlsx")
msg.attach(part)
# 메일 보내고 서버 끄기
s.sendmail(me, you, msg.as_string())
s.quit()
뉴스를 수집해서 엑셀로 저장한 뒤 그 엑셀파일을 첨부해서 메일을 보내는 코드이다.
짬뽕!
from bs4 import BeautifulSoup
from selenium import webdriver
from openpyxl import Workbook
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
## 스크래핑
driver = webdriver.Chrome('chromedriver')
url = "https://search.naver.com/search.naver?where=news&sm=tab_jum&query=추석"
driver.get(url)
req = driver.page_source
soup = BeautifulSoup(req, 'html.parser')
wb = Workbook()
ws1 = wb.active
ws1.title = "articles"
ws1.append(["제목", "링크", "썸네일"])
articles = soup.select('#main_pack > section.sc_new.sp_nnews._prs_nws > div > div.group_news > ul > li')
for article in articles:
a_tag = article.select_one('div.news_wrap.api_ani_send > div > a')
title = a_tag.text
url = a_tag['href']
# comp = article.select_one('#text')
# comp = article.select_one('div.news_wrap.api_ani_send > div > div.news_info > div.info_group > a.info.press > span').text.split(' ')[0].replace('언론사','')
preview = article.select_one('div.news_wrap.api_ani_send > a > img')['src']
print(preview)
ws1.append([title, url, preview])
driver.quit()
wb.save(filename='articles.xlsx')
# 메일 보내기
# 보내는 사람 정보
me = "@gmail.com"
my_password = ""
# 로그인하기
s = smtplib.SMTP_SSL('smtp.gmail.com')
s.login(me, my_password)
# 받는 사람 정보
you = "@naver.com"
# 메일 기본 정보 설정
msg = MIMEMultipart('alternative')
msg['Subject'] = "메리추석"
msg['From'] = me
msg['To'] = you
# 메일 내용 쓰기
content = "복 많이 받을거야"
part2 = MIMEText(content, 'plain')
msg.attach(part2)
# 파일 첨부하기
part = MIMEBase('application', "octet-stream")
with open("articles.xlsx", 'rb') as file:
part.set_payload(file.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment", filename="merrychuseok.xlsx")
msg.attach(part)
# 메일 보내고 서버 끄기
s.sendmail(me, you, msg.as_string())
s.quit()