생각하는 감쟈

[Python] 3-2) 정규표현식, 워드클라우드 본문

Language/Python

[Python] 3-2) 정규표현식, 워드클라우드

생각하는 감쟈🥔 2023. 4. 6. 00:45

 

 

 

 

 

14일차 (23.03.30)

 

 


2. 데이터 수집

3) 정규표현식

4) 네이버 뉴스에서 URL과 제목 가져와서 파일로 저장

6) 표에서 내용 가져오기

 

3. 워드클라우드

1) 네이버에서 오늘자 랭킹뉴스 가져오기

2) 워드클라우드 만들기

2-1 글자이상 명사만 추출

2-2 한글폰트 설치하고 지정

2-3 파일로 저장

3) 마스크 씌우기

4) 스탑워드 적용하기


정규 표현식

[abc] 대괄호 안에 있는 문자 1개 인식 a or b or c와 같음

[^abc] 대괄호 안에 있는 문자가 아닌 문자를 인식(NOT 연산) a, b, c 이외의 문자

[0-9] 0부터 9까지의 범위 중 한 문자 인식

[a-zA-Z] 소문자, 대문자를 인식

[a-z&&[def]] a~z까지 1문자 and d/e/f 중 1글자 인식

[ ] 문자의 집합 또는 범위를 나타냄 대괄호 안의 ^ 표시는 NOT을 뜻함

{ } 횟수 또는 범위를 나타낸다.

( ) 소괄호 안의 문자를 하나의 그룹으로 인식

. 임의의 한 문자 단, \는 넣을 수 없음

* 앞 문자가 0개 이상 존재

+ 앞 문자가 1개 이상 존재

? 앞 문자가 없거나 하나 존재

^ 문자열의 시작

$ 문자열의 종료

| 패턴 안에서 or 연산 수행

&& 패턴 안에서 and 연산 수행

\s 공백문자. \t\n\x0B\f\r

\S 공백 문자가 아닌 나머지 문자 [^\s]와 동일

\w 영숫자와 _(언더바) [a-zA-Z_0-9]와 동일

\W 영숫자를 제외한 문자 [^\w]와 동일

\d 숫자 [0-9]와 동일

\D 숫자를 제외한 모든 문자 [^0-9]와 동일

\ 확장문자 \ 다음에 일반 문자가 오면 특수문자로 취급

(?i) 대소문자를 구분하지 않음

 

 

네이버 뉴스에서 URL과 제목 가져와서 파일로 저장

#네이버 뉴스에서 url과 제목 가져와서 파일로 저장

import requests
from bs4 import BeautifulSoup
import pandas as pd

# 힌트: url은 title 안에 들어 있다. title['href']

# 뉴스 제목만 csv 파일로 저장했던 코드를 수정해서 만들어 보자 (어제 수업에서 복사)
def getNews(keyword, p, sort, fname):
    newslist = []

    for k in keyword.split():
        print("\n\n===",k,'===')
        for i in range(p):  # 5==>0,1,2,3,4
            start = i * 10 + 1  # 1,11,21,31,41
            url = f"https://search.naver.com/search.naver?where=news&sm=tab_pge&query={k}&sort={sort}&photo=0&field=0&pd=0&ds=&de=&cluster_rank=13&mynews=0&office_type=0&office_section_code=0&news_office_checked=&nso=so:r,p:all,a:all&start={start}"
            response = requests.get(url)

            html = response.text
            bs_obj = BeautifulSoup(html, "html.parser")

            titles = bs_obj.select('.news_tit')

            for title in titles:
                newslist.append(title.text)
                print(title["href"])

    df = pd.DataFrame({'뉴스제목': newslist})
    df.to_csv(fname)
    

keyword = input('어떤 내용을 검색하시겠습니까? ')
page = int(input('몇 번째 페이지까지 읽어오겠습니까? '))
getNews(keyword, page, 1, "네이버뉴스.csv")

df = pd.read_csv("네이버뉴스.csv")
df
 

 

#커피쇼핑몰에서 상품정보 가져오기
import requests
from bs4 import BeautifulSoup
import pandas as pd
import re


regex = re.compile(r'\d{1,3}(,\d{3})*')


# 상품명과 가격 정보를 저장할 리스트
mega_names =[]
mega_prices = []

for page in range(1,6):
    url = f'https://www.megacoffee.co.kr/goods/goods_list.php?page={page}&cateCd=001'

    # 해당 url에서 가져온 데이터 저장
    data = requests.get(url)

    # html.parser를 이용해 content만 가져옴
    soup = BeautifulSoup(data.content, 'html.parser')

    # 태그가 div이고 class='item_cont'인 부분만 리스트로 가져옴
    lists = soup.find_all('div', attrs={'class':'item_cont'})

    # 리스트 하나에 제품 정보 하나가 있으므로, 하나씩 순회하며 item_tit_box와 item_money_box에 해당하는 값만 읽어옴
    for tr in lists:
        name = tr.select_one('div.item_info_cont > div.item_tit_box > a > strong').text
        price = tr.select_one('div.item_info_cont > div.item_money_box > strong').text.strip()
        # '34,500\n\t\t\t\t\t\t\t원'
        #price_real = price[0:7].strip()
        
        price_real = regex.search(price)
        #print(price_real)
        mega_names.append(name)
        mega_prices.append(price_real.group())

mega_df = pd.DataFrame({"상품명":mega_names, "가격":mega_prices})
mega_df.to_csv('mega_coffee.csv')

mega_df.head(5)
 
# 메가커피에서 스타벅스 제품만 2페이지 가져와서 "starbucks.csv"에 저장하기

import requests
from bs4 import BeautifulSoup
import pandas as pd
import re


regex = re.compile(r'\d{1,3}(,\d{3})*')


# 상품명과 가격 정보를 저장할 리스트
mega_names =[]
mega_prices = []

for page in range(1,3):
    url = f'https://www.megacoffee.co.kr/goods/goods_list.php?page={page}&brandCd=391'

    # 해당 url에서 가져온 데이터 저장
    data = requests.get(url)

    # html.parser를 이용해 content만 가져옴
    soup = BeautifulSoup(data.content, 'html.parser')

    # 태그가 div이고 class='item_cont'인 부분만 리스트로 가져옴
    lists = soup.find_all('div', attrs={'class':'item_cont'})

    # 리스트 하나에 제품 정보 하나가 있으므로, 하나씩 순회하며 item_tit_box와 item_money_box에 해당하는 값만 읽어옴
    for tr in lists:
        name = tr.select_one('div.item_info_cont > div.item_tit_box > a > strong').text
        price = tr.select_one('div.item_info_cont > div.item_money_box > strong').text.strip()
        # '34,500\n\t\t\t\t\t\t\t원'
        #price_real = price[0:7].strip()
        
        price_real = regex.search(price)
        #print(price_real)
        mega_names.append(name)
        mega_prices.append(price_real.group())

mega_df = pd.DataFrame({"상품명":mega_names, "가격":mega_prices})
mega_df.head()
 

 

 

표에서 내용 가져오기

td0 = []
td2 = []
td3 = []

for tr in trs:
    tds = tr.findAll('td')
    # print(tds[0].text.strip())
    # print(tds[2].text.strip())
    # print(tds[3].text.strip())
    # print(tds[4].text.strip())
    # print(tds[5].text.strip())
    # print()
    td0.append(tds[0].text.strip())
    td2.append(tds[2].text.strip()[:-3])
    td3.append(tds[3].text.strip())
df = pd.DataFrame({'번호': td0, '제품명': td2, '제조사': td3})
df.head()
 

 


워드 클라우드

 

네이버에서 오늘자 랭킹뉴스 가져오기

from datetime import datetime

# 현재 날짜와 시간을 나타내는 datetime 객체 생성
now = datetime.now()

# 연도, 월, 일 추출
year = str(now.year)
month = str(now.month).zfill(2)
day = str(now.day).zfill(2)

# 연도, 월, 일을 이용하여 문자열 생성
date = year + month + day

print(date)  # 출력: 예를 들어 20230330
 

 

워드클라우드 만들기

!pip install konlpy # 형태소 분석
 
from wordcloud import WordCloud
from collections import Counter
from konlpy.tag import Okt
 

 

# 명사만 추출

okt = Okt()
nouns = okt.nouns(title_list) # 명사만 추출
print(nouns)
 
# 2글자 이상 명사만 추출

words = [n for n in nouns if len(n) > 1] 

# words=[]
# for n in nouns:
#     if len(n)>1:
#         words.append(n)

counted_words = Counter(words)
print(counted_words)
 

한글폰트 설치하고 지정

!apt-get update -qq
!apt-get install fonts-nanum* -qq
 

 

import matplotlib.font_manager as fm
sys_font = fm.findSystemFonts()

fonts = [f for f in sys_font if 'Nanum' in f]
fonts
 
# 워드클라우드 생성
wc = WordCloud(font_path=fonts[0],  # font_path='/usr/share/fonts/truetype/nanum/NanumMyeongjoEco.ttf'
               background_color="white",
               width=400, height=400, scale=2.0, max_font_size=250)
gen = wc.generate_from_frequencies(counted_words)
 
# 워드클라우드 그리기

import matplotlib.pyplot as plt

plt.figure(figsize=(6,6))
plt.imshow(wc)
plt.axis('off')
plt.show()
 

 

 

마스크 씌우기

from PIL import Image
import numpy as np

mask = np.array(Image.open("img.png"))
 
wc = WordCloud(font_path=fonts[0],  # font_path='/usr/share/fonts/truetype/nanum/NanumMyeongjoEco.ttf'
               background_color="white",
               mask = mask,
               width=400, height=400, scale=2.0, max_font_size=250)
wc.generate_from_frequencies(counted_words)

plt.figure(figsize=(6,6))
plt.imshow(wc)
plt.axis('off')
plt.show()
 
!pip install kiwipiepy


from kiwipiepy import Kiwi

kiwi = Kiwi()

result = kiwi.tokenize(title_list)

words = [n.form for n in result if n.tag in ['NNG', 'NNP']]
print(words)
 

스탑워드 적용하기

stopwords = set()
stopwords.add("전두환")
stopwords.add("대통령")

# stopwords = {"대통령","전두환"}

no_stopwords = [n for n in nouns if not n in stopwords]

words = [n for n in no_stopwords if len(n) > 1] 
counted_words = Counter(words)
 
wc = WordCloud(font_path=fonts[0],  # font_path='/usr/share/fonts/truetype/nanum/NanumMyeongjoEco.ttf'
               background_color="white",
               mask = mask,
               width=400, height=400, scale=2.0, max_font_size=250)
wc.generate_from_frequencies(counted_words)

plt.figure(figsize=(6,6))
plt.imshow(wc)
plt.axis('off')
plt.show()
 
!pip install kiwipiepy
 
# 개인 PC에 JVM이 설치되어 있지 않은 경우

from kiwipiepy import Kiwi
kiwi = Kiwi()

result = kiwi.tokenize(title_list)
words = [n.form for n in result if n.tag in ['NNG', 'NNP']]
print(words)
 
counted_words = Counter(words)

# 폰트는 본인 노트북에서 폰트 찾아서 경로를 넣으세요. C:\Windows\Fonts\......
# mask를 씌울 경우, 이미지파일을 ipynb파일과 같은 위치에 넣거나, 전체 경로를 다 적어주세요.
wc = WordCloud(font_path=fonts[0],  # font_path='/usr/share/fonts/truetype/nanum/NanumMyeongjoEco.ttf'
               background_color="white",
               mask = mask,
               width=400, height=400, scale=2.0, max_font_size=250)
wc.generate_from_frequencies(counted_words)

plt.figure(figsize=(6,6))
plt.imshow(wc)
plt.axis('off')
plt.show()
 

 

 

 

 

 

 

 

 

#ABC부트캠프 #부트캠프 #유클리드소프트 #파이썬 #고용노동부 #한국산업인력공단 #청년친화형 #ESG지원사업 #대전 #서포터즈 #python #Ai #Bigdata #cloud #대외활동 #대학생 #daily

 

Comments