2022.7.04~2022.07.08
구름 X 전주 ict 이노베이션 스퀘어의 온라인 코딩교육 내용을 정리하였습니다.
셀레나 고메즈 - 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 |