본문 바로가기
NLP

크롤링 1

by 볼록티 2019. 11. 21.
728x90
반응형

 

크롤링이란 : web에 존재하는 contents를 수집하는 작업을 말합니다.

 

- 크롤링을 할 때 사용하는 방법들은 아래와 같습니다.

 

1. HTML 페이지를 가져와서, HTML/CSS 등을 파싱하고, 필요한 데이터를 추출하는 방법. 

2. Open API(Rest API)를 제공하는 서비스에 Open API를 호출해서, 필요한 데이터를 추출하는 방법.

3. Selenium등 브라우저를 프로그래밍으로 조작해서, 필요한 데이터를 추출하는 방법.

 

 

각 방법을 수행하기 위하여 네이버 뉴스 기사를 사용하였습니다.

 

 

이 페이지에서는 아래의 모듈을 다루게 됩니다.

 

- from bs4 import BeautifulSoup # 추출

- import requests # html불러오기

- from urllib.request import urlopen # html불러오기 requests는 openurl과 유사

 

from bs4 import BeautifulSoup
import requests

bs4 패키지에서 BeautifulSoup 를 import합니다.

BeautifulSoup는 XML과 HTML형식으로 된 문서를 분해할 수 있는 분해기(Parser)라고도 합니다.

python 에서 requests는 http 요청을 보내는 모듈이라고 할 수 있습니다.

 

bs4패키지가 설치가 안되어 있다면, window환경에서는 cmd창에서 pip install bs4로 설치할 수 있있습니다.

page = requests.get("https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=100&oid=079&aid=0003293899")
soup = BeautifulSoup(page.content, 'html.parser')
soup.body # 크롤링한 html 텍스트를 볼 수 있습니다.

 

위의 코드를 통해서 크롤링 하고자 하는 페이지를 html형식으로 불러오게 됩니다. 이제 크롤링하고자 하는 부분을 parser하는 과정에 대해 알아보겠습니다.

 

div4 를 실행하면 크롤링한 기사 내용 부분을 확인할 수 있다.
끝마다 [0]을 붙여 원소를 지정해줌으로써 계속 bs4.element.Tag 형식을 유지할 수 있다.

type(soup.body)
#'bs4.element.Tag' type을 확인할 수 있습니다.

div = soup.body.find_all('div', id='wrap')[0]
div1 = div.find_all('table', class_='container')[0]
div2 = div1.find_all('div', id='main_content')[0]
div3 = div2.find_all('div', id='articleBody')[0]
div4 = div3.find_all('div', id='articleBodyContents')[0]

div4.text # bs4.element.Tag 형식일 경우 .text 함수를 통해 텍스트 부분만 추출해낼 수 있습니다.

 

 

 

이번엔 for 문을 통해서 추출해보도록 하겠습니다.

 

아까와 동일한 방법으로 끝까지 찾아나갑니다. * type에 계속 유의하면서 진행하는게 좋습니다.

div = soup.body.find_all('div', id='wrap')[0]
div1 = div.find_all('table', class_='container')[0]
div2 = div1.find_all('div', id='main_content')[0]
div3 = div2.find_all('div', id='articleBody')[0]
div4 = div3.find_all('div', class_='link_news')[0]

links=div4.find_all("li") # 마지막 'div' 속에 중복된 li들을 전부 추출합니다.
type(links)
#bs4.element.ResultSet

-> body는 html의 형식 중 'body'부분을 말합니다. soup.body.find_all()은 soup에서 body부분에서 find_all함수를 실행하는 것입니다.

 

 

for 문을 활용하여 중복된 li들을 리스트에 담아봅니다.

#ResultSet 속에 있는 원소들을 차례대로 텍스트만 추출하여 리스트에 추가시킵니다.

text_list=[]
for i in links:
    text_list.append(i.text)

-> 각 원소( 'li' ) 의 텍스트를 추출합니다.

 

#ResultSet 속에 원소들이 가진 <a href  ... ... ... 를 하나씩 추출하여 리스트에 추가합니다.
links_list=[]
for i in links:
    links_list.append(i.a["href"])

-> 각 원소( 'li' ) 하위에 'a href' 에 담긴 링크 텍스트를 하나씩 가져옵니다.

 

 

 

requests 함수 말고 urlopen을 사용하여 크롤링하기.

 

from urllib.request import urlopen

page = urlopen("https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=100&oid=079&aid=0003293899")
soup = BeautifulSoup(page, 'html.parser')
soup.body.find_all('div', id='wrap') # requests를 사용할 때 처럼 사용할 수 있다.

 

다음과 같이 여러 응용이 가능하다.

for meta in soup.head.find_all('meta'):
    print(meta.get('content'))

-> 각 'meta'속 내용을 추출

 

 

soup.head.title # 기사의 제목을 리턴합니다.

 

 

page = urlopen("https://news.naver.com/main/read.nhn?mode=LSD&mid=shm&sid1=100&oid=079&aid=0003293899")
soup = BeautifulSoup(page, 'html.parser')

for link in soup.find_all('a'):
    print(link.text.strip(), link.get('href'))

-> soup 하위에 모든 'a'를 차례로 읽어가며, strip()함수로 양끝을 정리해준것과 아까 링크를 추출할 때처러 하기 위해 get('href')를 사용하여 추출한다.

 

 

 

 

 

이 노트는 서울과학기술대학교 이영훈 교수님의 수업에 사용된 내용입니다.

 

 

 

 

728x90
반응형

'NLP' 카테고리의 다른 글

코사인 유사도를 활용한 유사 문서 검색  (0) 2019.11.22
뉴스 기사 분류  (0) 2019.11.22
크롤링 4  (0) 2019.11.21
크롤링 3  (0) 2019.11.21
크롤링 2  (0) 2019.11.21

댓글