본문 바로가기
Python 과 머신러닝/III. 머신러닝 모델

[Python 머신러닝] 10장. 텍스트 마이닝 - (1) 크롤링 (Crawling)

by JoyfulS 2019. 10. 31.

 

실습 전 준비사항 (미리 깔아둬야하는 패키지 등)

[Python 머신러닝] 10장. 텍스트 마이닝 (Text Mining) 개요 & 패키지 준비

 

 

< 실습한 내용 >

1. URL Request & HTML Parsing

2. tag 이름으로 찾기

3. 선택자(selector) 이용하기

4. 뉴스 페이지 크롤링해보기

 

 

1. URL Request & HTML Parsing

"""
URL Request
- 태그 이름 찾기 : find('a'), find_all('a')
"""

from bs4 import BeautifulSoup # html 파싱 (html 문서로 변환시켜주는 역할)
import urllib.request as req # 원격 서버 파일 요청

url = "http://www.naver.com/index.html"


# 1. 원격 서버 파일 요청
req = req.urlopen(url) # web 문서 get
data = req.read() # text 형태 읽음
data


# 2. decode & html 파싱
src = data.decode('utf-8') # 한글이 깨지지 않도록 decoding
src # text 형태
html = BeautifulSoup(src, 'html.parser') # html 파싱 => html 태그 (웹문서) 형태
html


# 3. 태그 찾기 -> 내용
'''
element : <시작태그  속성='값'> 내용 </종료태그>
'''
# 1) 1개 tag 찾기
link = html.find('a') # 최초 발견 태그 가져오기

link

# 태그 내용
link.string # '연합뉴스 바로가기'

# 2) n개 tag 찾기
links = html.find_all('a') # 전체 < a> 태그 가져오기 => list 형태로

type(links) # bs4.element.ResultSet
len(links)

link_data = [] # 빈 list
for link in links : # 345
    data = link.string
    print(data) # 내용
    if data : # None 제외
        link_data.append(link.string)
        
link_data

 

 

 

2. tag 이름으로 찾기

"""
tag 이름으로 찾기
 - find('tag')
 - find_all('tag')
"""

from bs4 import BeautifulSoup

# 1. 로컬 서버 파일 읽기
file = open("../data/test.html", encoding = 'utf-8')
text = file.read()
text


# 2. html 파싱
html = BeautifulSoup(text, 'html.parser')
html


# 3. 태그 내용 가져오기

# 1) tag 이름
h1 = html.html.body.h1 
h1


h1.string # ' 시멘틱 태그 ?'

# 2) find('tag') 함수
h2 = html.find('h2')
h2.string # ' 주요 시멘틱 태그 '

# 3) find_all('tag') 함수
lis = html.find_all('li') # li 전체 tag
lis

li_data = []
for li in lis :
    data = li.string
    #print(li.string)
    if data :
        li_data.append(li.string)


li_data

 

 

 

3. 선택자(selector) 이용하기

"""
선택자(selector) 이용 내용 추출하기
 - 웹 문서 디자인용으로 사용
 - 특정 tag의 속성 사용
 - id(#), class(.)
 - find('tag') vs select('tag#id')
"""

from bs4 import BeautifulSoup

# 1. html 파일
file = open("../data/selector.html", encoding='utf-8')
src = file.read()


# 2. html 파싱
html = BeautifulSoup(src, "html.parser")
html


# 3. selector(선택자) 이용해서 내용 가져오기

# 1) id 선택자
# select_one : element 1개 가져옴
table = html.select_one("table#tab") # ("tag#id")
table

# 2) id 선택자 > 하위 태그
# select : element n개 가져옴
ths = html.select("table#tab > tr > th") # '>'를 통해 계층적으로 접근
ths            

for th in ths :
    print(th.string)

# 3) class 선택자
trs = html.select("table#tab > tr.odd") # 테이블의 3,5행
trs

for tr in trs :
    tds = tr.find_all('td') # 의 하위 태그인  태그만 선별
    for td in tds :
        print(td.string)

# 4) tag[selector='값']
trs = html.select("tr[class='odd']")
trs

for tr in trs :
    tds = tr.find_all('td') # 의 하위 태그인  태그만 선별
    for td in tds :
        print(td.string)

 


4. 뉴스 페이지 크롤링해보기

"""
news Crawling
 url : http://media.daum.net
"""

import requests # 원격 서버 data 요청
from bs4 import BeautifulSoup # html parser

url = "http://media.daum.net"

# 1. url 요청
req = requests.get(url)
print(req) # 
src = req.text # text형식으로

# 2. html 파싱
html = BeautifulSoup(src, "html.parser")
html

# 3. tag[속성='값']
links = html.select("a[class='link_txt']")
len(links) # 115

links[:10]
links[-10:]

# 4. tag 내용 수집
crawling_data = []

for a in links :
    #print(a.string)
    cont = a.string
    if cont : # None 제외
        cont = str(cont)
        # strip() : 문장 끝 불용어 제거
        crawling_data.append(cont.strip())
        
crawling_data


# Today, 실시간 검색어 제외
index = 0
for i, c in enumerate(crawling_data) :
    if c == '코스피' :  # 웹페이지를 살펴보면 뉴스기사 다음에 코스피 등장, 이후가 필요없는 정보들
        print('index =', i)
        index = i # 49
        
crawling_data = crawling_data[:index]
crawling_data


# 5. file save 
type(crawling_data) # list

import pickle

# save
file = open("../data/data.pickle", mode='wb') # 'wb' : write, binary(이진)
pickle.dump(crawling_data, file) # 원래 list 형태를 그대로 저장 -> 불러올때도 그대로 불러와짐

# load
file = open("../data/data.pickle", mode='rb') # 'rb' : read, binary
crawling_data2 = pickle.load(file)

crawling_data2

댓글