본문 바로가기

STUDY

파이썬 스터디 ver3. 3주차

2022.7.04~2022.07.08

구름 X 전주 ict 이노베이션 스퀘어의 온라인 코딩교육 내용을 정리하였습니다.


https://youtu.be/XEmLQMmi7iw

셀레나 고메즈 - Who says. 우연히 떼창 쇼츠가 알고리즘에 떠서 보다가 알게 된 노래에요. 가사가 너무 예뻐서 가져왔어요.


 

Web Crawling: 크롤러가 링크를 통해 웹을 돌아다니는 것. 

Web Scraping: 웹페이지에서 원하는 자료를 긁어오는 것. 웹 데이터 구조 분석이 필요함.

프론트엔드: 웹사이트 계층구조, 디자인, 페이지 동작을 구현함.

백엔드: URL에 대응될 함수를 데이터베이스에서 관장함.

 

requests 라이브러리: 웹 페이지 데이터를 받기 위한 라이브러리. 

urllib 라이브러리: url관련 데이터를 처리하는 라이브러리. 사실 requests와 뭐가 다른지 모르겠다...

 

BeautifulSoup 라이브러리: (requests로 받은 것 중)원하는 데이터를 추출하기 위한 라이브러리

- 기본형 `BeautifulSoup(markup, parser)`. 이때 markup은 requests로 요청/응답받은 변수, parser는 해석해주는 것(lxml, html.parser, html5lib)

- find(tag), find(id=@), find(tag, attrs{속성:속성값})으로 원하는 태그를 하나 반환할 수 있음

- find_all(tag), find_all(tag, limit=N)으로 여러 개(리스트 형태)의 태그를 받을 수도 있음

- select_one / select(CSS selector): CSS선택자를 활용해 원하는 태그를 하나/여러 개 받아옴

- find는 HTML tag를 통한 크롤링, select는 CSS를 통한 크롤링에 사용됨(select는 하위태그를 >로 사용)

from urllib.request import urlopen
from bs4 import BeautifulSoup
import urllib.parse as parse
import urllib.request as req

url = "https://metamon-ditto.tistory.com/"
res = req.urlopen(url)
soup = BeautifulSoup(res, 'html.parser')
soup.select_one('title') #<title>메타몽이되고싶어</title>
soup.select_one('title').get_text() #'메타몽이되고싶어'

 

Web Scraping

1. URL 분석(패턴 존재 여부, query 종류)

2. URL 구성(str로 만들기)

from urllib.request import urlopen
from bs4 import BeautifulSoup

HTTP_response = urlopen(URL) #혹은 request.get(URL).content
HTML_source = BeautifulSoup(HTTP_response, 'html.parser')

3. HTML 태그 꺼내기(필요한 거 꺼내기)

HTML_source.find('metamon') #metamon태그 (하나)찾기
HTML_source.find_all('pokemon') #pokemon태그 (모두)찾기 #결과 type은 리스트와 유사한 bs4.element.ResultSet
HTML_source.find('metamon').attrs #어트리뷰트 찾기
HTML_source.find('metamon').get_text() #태그 내 텍스트만 찾기
HTML_source.find_all('metamon', {'num':'231'}) #metamon태그에서 num클래스가 231인 것 모두 찾기

 

 

Selenium: 웹 페이지를 테스트(제어)하기 위한 자동 테스팅 모듈. 주로 웹드라이버를 사용함

!apt-get install -y fonts-nanum* #한글폰트 설치

!pip install Selenium
!apt-get update
!apt install chromium-chromedriver
!cp /usr/lib/chromium-browser/chromedriver/usr/bin

from selenium import webdriver #크롬드라이버 사용
wd = webdriver.Chrome('chromedriver', chrome_options=chrome_options)

- driver.find_element(단수), driver.find_elements(복수)로 원하는 것을 가져옴

웹페이지 이동은 셀레니움, 스크레이핑은 뷰티풀수프를 사용한다.

#네이버에 검색해보기

driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options) #웹드라이버 생성
driver.get('https://www.naver.com') #네이버 접속시키기
search_bar = driver.find_element(By.CLASS_NAME, 'input_text') #검색창 찾기
search_bar.send_keys('메타몽') #검색어 입력
search_bar.send_keys(Keys.ENTER) #엔터 누르기(검색 실행)

driver.quit() #종료해주기

 

- 위 사진은 중간중간 driver.save_screenshot으로 캡쳐해 본 것. 순서대로 네이버 접속 > 검색어 입력 > 검색 실행

 

자연어 분석(NLTK)

1. 텍스트 데이터 준비(str)

2. Tokenize, POS(Part-Of-Speech, 품사) Tagging, Stopwords제거, Lemmatizing

- tokenize: 형태소 분석

- pos tagging: 품사 표시(N으로 시작하는 건 명사(Noun)계열, V로 시작하는 건 동사(Verb)계열 등)

- stopwords: 불용어(조사 등)

- Lemmatizing: 단어의 기본형 lemma를 찾아주는 것. 디폴트가 명사이므로 특정 품사를 염두하는 경우 적어주어야 함

import nltk; from nltk.corpus import stopwords

sentence = "Metamon is wonderful, AWESOME, fantastic pokemon" #1단계
tokens = nltk.word_tokenize(sentence) #2단계: Tokenize
['Metamon', 'is', 'wonderful', ',', 'AWESOME', ',', 'fantastic', 'pokemon'] #tokens
#2단계: Stopwords 제거 + lemmatizing
stop_word = stopwords.words('english')
stop_word.append(',')
lemmatizer = nltk.wordnet.WordNetLemmatizer()

rslt = []
for words in tokens:
    if words.lower() not in stop_word: #stopwords들은 모두 소문자임
        rslt.append(lemmatizer.lemmatize(words))

pos_rslt = nltk.pos_tag(rslt) #2단계: POS tagging
['Metamon', 'wonderful', 'AWESOME', 'fantastic', 'pokemon'] #rslt
[('Metamon', 'NNP'), ('wonderful', 'JJ'), ('AWESOME', 'NNP'), ('fantastic', 'JJ'), ('pokemon', 'NN')] #pos_rslt

3. 활용

- Collections의 counter를 사용해서 (lemmatizing으로 얻은)원형과 그 개수를 얻어 plot을 그리거나 할 수 있음

- 필요한 정보만 골라내기 위해 정규표현식을 사용하는 경우가 많음 (유튜브 찾아보자..)

 

TF-IDF Vectorizer

- Term-Frequency-Inverse Document Frequency Vectorizer

- 특정 단어(문장 구성요소)의 중요도를 나타내는 지표. 포함 빈도가 높을수록 가중치를 줄임.

- `tf-idf(d,t) = tf(d,t)*idf(d,t)`. tf(d,t)는 단어의 빈도 수, idf(d,t)는 log(전체 문서 수/(1+단어 t를 가진 문서의 수)).

Cosine Similarity: 코사인 유사도

- 두 벡터 사이 각도의 코사인 값을 이용해 측정하는 값(=두 벡터의 유사한 정도)

- -1에서 1사이의 값을 가지며, 절대값이 1에 가까울수록 완전히 다르거나 같고 0이면 서로 독립임을 의미함

from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity

file = open('we both reached for the gun.txt', 'r', encoding='utf-8')
lines = file.readlines() #모든 내용을 읽어 와 리스트로 저장함
doc1 = ' '.join(lines) #str로 만듦

file = open('cell block tango.txt', 'r', encoding='utf-8')
lines = file.readlines()
doc2 = ' '.join(lines)

corpus = [doc1, doc2]
vectorizer = TfidfVectorizer() #TfidfVectorizer 만듦
chicago = vectorizer.fit_transform(corpus).todense() #이 때 chicago는 np.matrix
cosine_similarity(chicago[0], chicago[1]) #코사인 유사도 계산: 0.23

 

 

0.013318 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.009476 ... 0.000000 0.000000 0.009476 0.018952 0.000000 0.492781 0.013318 0.085285 0.000000 0.026637
0.000000 0.012082 0.036246 0.012082 0.024164 0.012082 0.012082 0.012082 0.012082 0.025789 ... 0.024164 0.048328 0.025789 0.008596 0.012082 0.000000 0.000000 0.232102 0.012082 0.000000

- 참고로 chicago를 DataFrame형식으로 만들면 위와 같다. 컬럼명(숫자)은 생략.

- vectorizer 뒤에 todense()를 써줘야 예쁘다..

+)

#CountVectorizer라는 것도 있다: 얘는 말 그대로 카운트만 함
vectorizer2 = CountVectorizer()
vectorizer2.fit(corpus)
pd.DataFrame(vectorizer2.transform(corpus).todense()) #얘는 빈도가 기록되어 있음

 

1 0 0 0 0 0 0 0 0 1 ... 0 0 1 2 0 37 1 9 0 2
0 1 3 1 2 1 1 1 1 3 ... 2 4 3 1 1 0 0 27 1 0

- 마찬가지로 컬럼명(숫자)는 생략.

- CountVectorizer의 경우 get_feature_names()로 각 컬럼명을 알 수 있다. 

'STUDY' 카테고리의 다른 글

파이썬 스터디 ver3. 5주차  (0) 2022.07.30
파이썬 스터디 ver3. 4주차  (1) 2022.07.24
파이썬 스터디 ver3. 2주차  (1) 2022.07.06
파이썬 스터디 ver3. 1주차  (0) 2022.06.27
파이썬 스터디 ver2. 5주차  (0) 2022.05.16