크롤링이란 : 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')를 사용하여 추출한다.
이 노트는 서울과학기술대학교 이영훈 교수님의 수업에 사용된 내용입니다.
댓글