멋쟁이사자처럼 X K-DIGITAL Training - 06.11
[이전] 2021.06.23 - [python/k-digital] - [K-DIGITAL] 파이썬 웹 크롤링 - 뉴스 기사 스크랩
이전 글에서는 '뉴시스' 언론사 기준으로 여러 기사 본문 스크랩핑을 진행하였다.
텍스트데이터 분석에 쓰기에 데이터 양도 부족할 뿐더러 몇 개의 뉴스에서는 본문이 제대로 스크랩되지 않아
수업시간에 배운대로 네이버 뉴스 기반으로 쓰기로 하였다.
내 나름대로 기사 본문 전처리를 한다고 하긴 하였는데 기사에 담긴 사진, 기자마다 기사를 시작하는 방식, 마지막에 본인의 이메일과 이름을 적는 방식이 조금씩 달라서(혹은 언론사가 달라서) 완벽하게 본문만 추출되지는 않았다😥
그래도 이전 스크랩보다는 훨씬 깔끔하여 이 방식으로 기사를 스크랩하고 텍스트 데이터 분석을 하기로 하였다.
* 네이버뉴스(연예란) 기준
[이전] 네이버 뉴스 탭에 검색
query = '배우 박정민'
url = "https://search.naver.com/search.naver?where=news&query=" + query
web = requests.get(url).content
source = BeautifulSoup(web, 'html.parser')
네이버 연예 뉴스 get 요청
url = 'https://entertain.naver.com/read?oid=018&aid=0004963324'
web = requests.get(url).content
source = BeautifulSoup(web, 'html.parser')
뉴스 제목
source.find('h2').get_text().strip()
>> '배우 이제훈, 매니지먼트 컴퍼니온 설립 [공식]'
뉴스 본문
article = source.find('div', {'id': 'articeBody'}).get_text().strip()
- 이메일부터 마지막까지 삭제
pattern = re.compile(r'[\s\Wa-zA-Z0-9]*@')
email_address = pattern.search(article)
# 삭제할 부분
article[email_address.start()+1:]
# 삭제
article = article[:email_address.start()+1]
* 기자마다 이름과 이메일 작성 방식이 달라 이메일만 삭제하도록 결정😅
- '처음 ~ 기자] ' 삭제
del_index = article.find('기자]')
# 삭제할 부분
article[:del_index+3] # 이제훈[이데일리 스타in 김가영 기자]
article = article[del_index+3:]
- 발행 시간
source.find('span', {'class': 'author'}).find('em').get_text()
>> 2021.06.21. 오전 9:17
- 발행사
source.find('img')['alt']
>> 이데일리
* 네이버뉴스 링크가 있는 '네이버뉴스' div를 통해 url 스크랩
네이버뉴스 url 스크랩
urls_list = []
for info in source.find_all('div', {'class': 'info_group'}):
for item in info.find_all('a', {'class': 'info'}):
if item.get_text() == '네이버뉴스':
urls_list.append(item['href'])
urls_list
각 뉴스마다 본문 스크랩
for url in urls_list:
if url.startswith('https://news.naver.com'):
try:
# 헤더 설정
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
content = requests.get(url, headers=headers).content
source = BeautifulSoup(content, 'html.parser')
# 기사제목
title = source.find('h2').get_text().strip()
# 기사날짜
date = source.find('span', {'class': 'author'}).find('em').get_text()
# 기사본문
article = source.find('div', {'id': 'articeBody'}).get_text().strip()
pattern = re.compile(r'[\s\Wa-zA-Z0-9]*@')
email_address = pattern.search(article)
article = article[:email_address.start()+1]
del_index = article.find('기자]')
article = article[del_index+3:]
# 언론사
press_company = source.find('img')['alt']
titles.append(title)
dates.append(date)
articles.append(article)
press_companies.append(press_company)
urls.append(url)
print('Title: {}'.format(url))
except:
print('*** error occurred at {} ***'.format(url))
else:
print('** (네이버뉴스x) Title: {}'.format(url))
데이터프레임 생성
df_article = pd.DataFrame({'Title': titles, 'Date': dates, 'Article': articles, 'URL': url, 'Press Company': press_companies})
뉴스 본문 스크랩
def scraping_news(url, titles, dates, articles, press_companies, urls):
if url.startswith('https://news.naver.com'):
try:
# 헤더 설정
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
content = requests.get(url, headers=headers).content
source = BeautifulSoup(content, 'html.parser')
# 기사제목
title = source.find('h2').get_text().strip()
# 기사날짜
date = source.find('span', {'class': 'author'}).find('em').get_text()
# 기사본문
article = source.find('div', {'id': 'articeBody'}).get_text().strip()
pattern = re.compile(r'[\s\Wa-zA-Z0-9]*@')
email_address = pattern.search(article)
article = article[:email_address.start()+1]
del_index = article.find('기자]')
article = article[del_index+3:]
# 언론사
press_company = source.find('img')['alt']
titles.append(title)
dates.append(date)
articles.append(article)
press_companies.append(press_company)
urls.append(url)
print('Title: {}'.format(url))
except:
print('*** error occurred at {} ***'.format(url))
else:
print('** (네이버뉴스x) Title: {}'.format(url))
데이터프레임 생성
def make_dateframe(titles, dates, articles, urls, presscompanies):
return pd.DataFrame({'Title':titles,
'Date':dates,
'Article':articles,
'URL':urls,
'PressCompany':presscompanies})
query = (input('검색할 단어를 입력하세요: '))
max_page = (input('검색할 총 페이지수를 입력하세요: '))
current = 1
last = (int(max_page)-1) * 10 + 1
base_url = 'https://search.naver.com/search.naver?where=news&query='
titles = []
dates = []
articles = []
press_companies = []
urls = []
while current <= last:
print('\n{}번째 페이지'.format((current//10) + 1))
print('{}번째 기사글부터 크롤링을 시작합니다.'.format(current))
# 페이지 이동
url = base_url + query + '&start=' + str(current)
web = requests.get(url).content
source = BeautifulSoup(web, 'html.parser')
# 각 페이지 url에서 기사 url 스크랩
urls_list = []
for info in source.find_all('div', {'class': 'info_group'}):
for item in info.find_all('a', {'class': 'info'}):
if item.get_text() == '네이버뉴스':
urls_list.append(item['href'])
# 각 url에 접속하여 기사 본문 스크랩
for url in urls_list:
scraping_news(url, titles, dates, articles, press_companies, urls)
# 접속 차단 방지를 위해 몇초간 sleep
time.sleep(5)
current += 10
# 데이터프레임 생성
df_news = make_dateframe(titles, dates, articles, urls, press_companies)
데이터프레임
df_news
엑셀 파일로 저장
df_news.to_excel('result_{}.xlsx'.format(datetime.now().strftime('%y%m%d_%H%M')), index=False, encoding='utf-8')
[K-DIGITAL] 파이썬 Selenium으로 크롤링하기(1) (0) | 2021.06.25 |
---|---|
[K-DIGITAL] 파이썬 텍스트 데이터 분석 (0) | 2021.06.25 |
[K-DIGITAL] 파이썬 웹 크롤링 - 뉴스 기사 스크랩 (0) | 2021.06.23 |
[K-DIGITAL] 세미프로젝트1. 서울시 자전거사고 분석(4) 추가, 수정 (0) | 2021.06.22 |
[K-DIGITAL] 세미프로젝트1. 서울시 자전거사고 분석(3) 상관관계 (0) | 2021.06.22 |
댓글 영역