Intro
여기선 데이터 분석을 위해 정보를 뽑아오는 크롤러를 제작하는 방식을 기술할 생각이다.
따라서 웹의 구조를 뽑아내어서 정보를 저장하는 과정을 수행하려 한다.
웹 관련 공부를 해본 사람은 알겠지만 정적/동적 형태에 따라서 뽑는 방법이 달라지며, 경우에 따라선 API를 활용해서 정보를 얻어야 하는 경우도 있다.
대표적으로 유튜브의 경우 API를 써서 정보를 얻는게 더 빠르다.
유튜브 데이터 뽑는 과정은 이전 포스트를 뒤져보면 나온다.
- 유튜브 데이터 뽑는 포스트: https://rubpcase.tistory.com/18
아무튼 여기선 먼저 단순한 정적 사이트의 정보를 끌어오도록 하겠다.
간단한 웹 크롤링
먼저 파이썬 환경에서 BeautifulSoup
모듈을 불러오도록 하자.
이때, 웹으로의 정보 요청을 위해 requests
도 같이 불러와주자.
from bs4 import BeautifulSoup
import requests
이후 특정 사이트의 정보를 끌어올 생각인데, 다음의 코드를 실행시켜주면 된다.
url = "https://rubpcase.tistory.com/" # 원하는 주소 입력.
resp = requests.get(store_url) # 페이지 요청
if resp.status_code == 200: # 요청이 됐으면,
page = store_response.text # 응답 결과 저장
soup = BeautifulSoup(page, 'html.parser') # 뷰티풀수프로 파싱
print(soup)
위 코드를 실행하면 아마 아래의 이미지와 같은 결과가 뜰 것이다.

우리가 F12키 눌러서 뜨는 개발자 환경에서 보이는 HTML 구조가 그대로 나왔다고 보면 된다.
그렇지 않고 뭔가 내용이 빠져있다 싶으면 해당 사이트에서 동적 컴포넌트를 사용한다는 건데, 그건 조금 차후에 다루도록 하겠다.
(살짝 적어보자면, 셀레니움이라는 친구가 추가로 필요하다.)

참고로 웹사이트에서 개발자 환경을 키면 위와 같이 형태가 뜬다.
보면 알겠지만 웹 구조가 앞선 콘솔 환경에 나와있는 것을 알 수 있다.
물론 저 상태론 정보가 정제되어 있지 않아서 쓰기 별로다.
따라서 적절히 구조를 파악해서 파싱하는 작업을 거쳐야 한다.
정보 파싱하기

먼저, 앞선 개발자 환경에서 다음 그림에 강조한 아이콘을 클릭해주자.

이후 위 사진처럼 웹페이지에서 추출할 영역에 커서를 가져다대면 정보가 보일 것이다.
이제 해당 영역을 클릭하면 자동으로 HTML 구조에서 어느 위치에 있는지를 알려준다.

앞선 제목에 해당되는 영역은 위와 같이 나왔음을 알 수 있다.
따라서 우린 해당 위치를 찾아서 정보를 뽑아내기만 하면 된다.

여기서 우클릭한 다음 복사를 선택해서 특정 형식으로 복사하는 선택지가 있긴 하다.
다만 지금은 이렇게 경로를 얻어내진 않을 것이고, 원초적으로 구조를 뜯어내는 과정을 먼저 해 볼 생각이다.
위 방식은 아마 다음 포스팅 때 할 생각이다.

보면 알겠지만, 위와 같이 강조한 영역이 제목 컨테이너를 구분하는 주 Tag가 되겠다.
정확힌 <html> -> ... -> <div id="container"> -> ... -> <strong>
내부의 내용이긴 하지만.
아무튼 위 구조를 토대로 다음의 형태로 코드를 변경하면 제목만 추출할 수 있게 된다.
url = "https://rubpcase.tistory.com/"
resp = requests.get(store_url)
if resp.status_code == 200:
page = store_response.text
soup = BeautifulSoup(page, 'html.parser')
arr = soup.find('div', {'id': 'container'}).find_all('strong', {'class': 'title'})
for a in arr:
print(a.text)
앞서 <div id="container">
는 맨 처음에 나오는 태그 하나만 고려하면 되니 그냥 find()
메소드를 사용했다.
반면, <strong class="title">
은 모든 제목마다 들어있기에 전부 찾아야 한다.
따라서 find_all()
을 사용해서 정보를 추출하였다.
이 경우 배열로 정보가 담기니 arr
라는 변수에 담아서 이후 출력을 수행해야 한다.
그리고 나오는 for
문에서 배열원소.text
를 써서 내부 데이터를 출력하면 된다.
해당 내부 데이터는 제목에 해당된다.

위와 같이 결과가 나오는 것을 알 수 있다.
(참고로 저 위에 추가된 import json
은 무시해도 된다. 지금 당장은 필요없다.)
추가 활동
추가로 정보를 뽑아내기 위해선 앞선 과정과 같이 구조파악 후 코드를 짜는 과정을 거쳐야 한다.

가령 위와 같이 게시물 날짜와 제목을 동시에 뽑아낼 수 있는데, 이 경우 앞선 코드에서 좀 수정이 필요하다.
앞선 코드는 직접 strong
태그에 접근했는데, 이 경우 먼저 날짜 정보를 담은 영역와 제목 정보를 담은 영역의 상위 태그를 먼저 접근해야 한다.
이후 각 for
루프를 돌면서 정보를 뽑아내야 할 것이다.
arr = soup.find('div', {'id': 'container'}).find_all("""채우기""")
for a in arr:
print(a.find("""채우기""").text, end='\t') # 날짜 정보
print(a.find('strong', {'class': 'title'}).text) # 제목 정보
위의 구조를 활용하면 적절히 코드를 짤 수 있을 것이다.
이건 그냥 유제로 남겨놓을까 한다.
마무리
일단 간단하게 맛보기로 뷰티풀수프를 사용해서 정보를 뽑아와봤다.
그 다음 포스트에선 조금 다른 방식으로 정보를 뽑고 저장하는 과정을 적으려 한다.
아까 나왔던 XPath와 같은 친구를 활용해서 앞선 과정을 다시 수행할 생각이다.
'데이터분석, 인공지능' 카테고리의 다른 글
[데이터분석] 구글 스프레드시트 활용하기 -2 (0) | 2022.03.06 |
---|---|
[데이터분석] 구글 스프레드시트 활용하기 -1 (0) | 2022.03.03 |
[인공지능] VQGAN과 CLIP을 활용한 이미지 생성 프로그램 (0) | 2022.02.21 |
[Hadoop] 하둡 관련 내용 & 명령어 간단 정리 (0) | 2022.02.13 |
[데이터분석] 유튜브 데이터 분석하기 -2 (0) | 2022.02.11 |