# 1. 중앙일보 스크롤링 함수
def choongang(keyword, num):
from selenium.webdriver.common.keys import Keys
from selenium import webdriver # 컴퓨터가 알아서 웹페이지를 움직일 수 있도록 하는 모듈
from bs4 import BeautifulSoup
import urllib
import re
import time
# 인공지능으로 중앙일보에서 검색했을때의 url 을 driver 가 인식할 수 있게 합니다.
list_url ="https://www.joongang.co.kr/search/news?keyword=" + keyword
driver = webdriver.Chrome("C:\\data\\chromedriver_win32\\chromedriver.exe")
driver.implicitly_wait(10)
driver.get(list_url)
for i in range(1,num+1): # 더보기 5번 눌러가며 아래로 내립니다.
더보기 = driver.find_element_by_css_selector('a.btn.btn_outline_gray')
더보기.send_keys('\n') # 엔터를 칩니다.
time.sleep(3)
driver.find_element_by_xpath("//body").send_keys(Keys.PAGE_DOWN) # 페이지 다운합니다
html = driver.page_source # 크롬브라우져에서 현재 불러온 html 소스를 가져옵니다
soup = BeautifulSoup( html, "html.parser") # html 코드를 beautifulsoup 으로 파싱합니다
base = soup.select("h2.headline > a") # html 코드에서 h2 테그의 headline 클래스의 자식 테그인
# a 테그의 html 문서들을 가져와라 ~
params=[] # 상세 기사 url 을 담을 비어있는 리스트를 만듭니다
for i in base[5:-5]: # 중앙일보의 경우는 많이 본 뉴스가 상위 5개, 하위 5개를 제외합니다.
params.append(i.get("href")) # a 테그 안에 있는 href 의 상세 url 을 가져옵니다.
f2 = open("c:\\data\\" + keyword + ".txt", "w", encoding="utf8")
cnt = 0
for k in params:
url = urllib.request.Request(k)
f = urllib.request.urlopen(url).read().decode("utf-8")
# 가져온 html 을 beautifulsoup 이 인식할 수 있도록 파싱합니다.
soup = BeautifulSoup( f, "html.parser")
for i in soup.find_all("div", class_ ="article_body fs3"):
cnt += 1
f2.write( str(cnt) + '. ' + re.sub('[\n\r\t]', '',i.text ) + '\n' )
f2.close()
driver.quit() # 끝나면 브라우져를 닫습니다.
# 2. 네이버 블러그 스크롤링 함수
def naver_blog(keyword,page_num):
# 모듈
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
from urllib import request as urlreq
import time
import re
# 크롬 드라이버
binary = "C:\\data\\chromedriver_win32\\chromedriver.exe"
# 브라우저를 인스턴스화
driver = webdriver.Chrome(binary)
params = []
for i in range(1,page_num+1):
url = "https://section.blog.naver.com/Search/Post.naver?pageNo="+str(i)+"&rangeType=ALL&orderBy=sim&keyword="+keyword
driver.get(url)
time.sleep(1)
html = driver.page_source
soup = BeautifulSoup(html,'html.parser')
base = soup.select('div.desc > a')
for i in base:
params.append(i.get('href'))
params2 = list(set(params))
from tqdm import tqdm_notebook # 속도 진행상황
f2 = open("c:\\data\\"+keyword+".txt","w",encoding = "utf8")
for k in tqdm_notebook(params2):
driver = webdriver.Chrome(binary)
driver.get(k)
element = driver.find_element_by_id("mainFrame") #iframe 태그 엘리먼트 찾기
driver.switch_to.frame(element)
html2 = driver.page_source
soup2 = BeautifulSoup(html2, 'html.parser')
#닉네임 크롤링
overlays = ".nick"
nick = driver.find_element_by_css_selector(overlays)
nickname = nick.text
nickname = re.sub('[\n\r\t]','',nickname)
#날짜 크롤링
try: # try 와 except 사이에 있는 코드를 돌리다가 데이터를 못받아오는 문제가 발생하면 except 이후의
# 의 코드를 실행해라 ~~
overlays = ".se_publishDate.pcol2"
date = driver.find_element_by_css_selector(overlays)
datetime = date.text
#내용 크롤링
content = soup2.select('div.se-component-content>div>div>p')
f2.write('\n\nurl주소 : '+k) # url 쓰기
f2.write('\n작성날짜: ' + datetime) # 날짜쓰기
f2.write('\n블로그 작성자['+nickname +']\n') # 닉네임 쓰기
for i in content:
if len(i.text) > 1:
f2.write(re.sub('[\n\r\t]','',i.text)+'\n') # 내용 크롤링하면서 쓰기
except:
continue # 지나쳐라 ~
f2.close()
# 3. 긍정, 부정 감정분석
def feeling(keyword):
#1. 텍스트 파일 3개를 불러옵니다.
ladybug = open('C:\\data\\'+keyword+'.txt', encoding='utf-8-sig')
positive = open('C:\\data\\pos_pol_word.txt',encoding='utf-8-sig')
negative = open('C:\\data\\neg_pol_word.txt',encoding='utf-8-sig')
#2. 텍스트 파일 3개를 읽어들입니다.
bug = ladybug.read() # 게시글을 문자형 변수 bug 에 담는다.
pos = set(positive.read().split('\n')) # 긍정단어를 엔터로 구분해서 리스트로 구성
neg = set(negative.read().split('\n')) # 부정단어를 엔터로 구분해서 리스트로 구성
#3. pos 와 neg 리스트에서 결측치를 제거합니다.
pos = list(filter(lambda x:x,pos))
pos1=set(pos) #중복되는 pos 의 단어를 제거
neg = list(filter(lambda x:x,neg))
# 단어 한자리는 삭제
pos1=list(filter(lambda x : True if len(x) > 1 else False, pos1))
neg=list(filter(lambda x : True if len(x) > 1 else False, neg))
#4. 긍정단어를 갯수와 함께 ladybug_pos.csv 에 저장합니다.
f2 = open("c:\\data\\ladybug_pos.csv", "w", encoding="utf-8-sig")
#pos1.remove('정')
pos1.append('멋지다')
for i in pos1: # 긍정 단어들을 하나씩 불러와서 i 변수 담습니다.
if i in bug: # bug 라는 문자열 변수 안에 i 변수의 있는 긍정단어가 포함되어 있다면
#print(i+','+ str(bug.count(i))) # 그 단어를 출력하고 그 건수를 출력해라 ~
f2.write( i + ',' + str(bug.count(i)) + '\n') # lady_bug_pos.csv 에 써라 ~
#4. 부정단어를 갯수와 함께 ladybug_neg.csv 에 저장합니다.
f3= open("c:\\data\\ladybug_neg.csv", "w", encoding="utf-8-sig")
neg.remove('ㅜㅜ ')
neg.remove('ㅠㅠ')
neg.remove(':)') # 스마일 페이스
neg.remove('저는')
neg.remove('마약')
neg.append('느끼하다')
for i in neg: # 부정 단어들을 하나씩 불러와서 i 변수 담습니다.
if i in bug: # bug 라는 문자열 변수 안에 i 변수의 있는 부정단어가 포함되어 있다면
#print(i+','+ str(bug.count(i))) # 그 단어를 출력하고 그 건수를 출력해라 ~
f3.write( i + ',' + str(bug.count(i)) + '\n') # ladybug_neg.csv 에 써라 ~
f2.close()
f3.close()
#2. ladybug_pos의 긍정단어 상위 20개 나열
import pandas as pd
pd.set_option('display.max_rows', None)
lady_pos = pd.read_csv("c:\\data\\ladybug_pos.csv" , header=None)
lady_pos.columns=['word', 'cnt']
lady_pos['순위']=lady_pos['cnt'].rank(method='dense', ascending=False).astype('int')
a=lady_pos[:].sort_values(by=['순위']).head(20) #head()를 이용 상위 20개만 출력
print('='*10,'긍정 단어 분석 내용입니다','='*10)
print(a)
#3. ladybug_neg의 부정 단어 상위 20개 나열
import pandas as pd
lady_neg = pd.read_csv("c:\\data\\ladybug_neg.csv" , header=None)
lady_neg.columns=['word', 'cnt']
lady_neg['순위']=lady_neg['cnt'].rank(method='dense', ascending=False).astype('int')
b=lady_neg[:].sort_values(by=['순위']).head(20)#head()를 이용 상위 20개만 출력
print('='*10,'부정 단어 분석 내용입니다','='*10)
print(b)
# 4. 메인 함수
def my_data():
print('='*21,'데이터 분석을 정말 편하게','='*21)
print('1. 중앙일보 기사 데이터 스크롤링 \n2. 네이버 블러그 데이터 스크롤링 \n3. 긍정, 부정 감성분석')
print('='*48)
num = int(input('▶ 번호를 선택하세요: '))
if num == 1 :
str1 = input('▶ 키워드를 입력하세요: ')
num1 = int(input('▶ 더보기를 몇 번 누를까요: '))
choongang(str1 , num1)
elif num == 2:
str2 = input('▶ 키워드를 입력하세요: ')
num2 = int(input('▶ 몇 페이지를 가져올까요? 한페이지에 7개의 블러그가 있습니다. '))
naver_blog( str2, num2)
elif num == 3:
str3 = input('▶ 키워드를 입력하세요: ')
feeling(str3)