«   2024/06   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
Recent Posts
Today
Total
관리 메뉴

짜리몽땅 매거진

[Python] beautifulsoap으로 당근마켓 정적 크롤링하기 본문

Data/Python

[Python] beautifulsoap으로 당근마켓 정적 크롤링하기

쿡국 2024. 4. 14. 18:31

 

당근마켓은 모바일에 최적화된 서비스 구조이기 때문에 웹크롤링을 통해서는 한정적인 정보만을 가져올 수 밖에 없다. 하지만 나의 동네 인기 매물을 검색했을 때 인기 게시글들의 '제목', '주소', '가격', '게시글 내용' 정보만 가져오면 되기 때문에 웹으로도 충분히 크롤링을 진행할 수 있었다. 

 

크롤링은 크게 두 가지 유형으로 분리되는데, 

 

정적 크롤링이란 멈춰있는 페이지의 HTML을 requests 혹은 urllib 패키지를 이용해 가져와서 beautifulsoap 패키지로 파싱(=복잡한 HTML 문서를 잘 분류, 정리하여 다루기 쉽게 바꾸는 작업) 하여 원하는 정보를 수집하는 과정이다.

 

동적 크롤링이란 계속 움직이는 페이지를 다루기 위해 selenium 패키지로 chromdriver를 제어하는 크롤링 과정을 말한다. 특정 url로 접속해서 로그인하거나 클릭하는 식으로 원하는 정보가 있는 페이지까지 도달하는 방식이다.

 

차이를 한 눈에 정리하면 아래와 같다.

  정적 크롤링 동적 크롤링
사용 패키지 requests / urllib selenium
수집 커버리지 정적 웹 페이지 정적 / 동적 웹 페이지
수집 속도 빠름 -> 특정 url의 HTML을 받아와서 수집하기 때문에 상대적으로 느림 -> 브라우저를 직접 조작하고 실행될 때까지 기다려야 하기 때문
파싱 패키지 beautifulsoup beautifulsoap / selenium
범용성 좋지 않음 좋음

아래는 당근마켓에 '특정 동네'를 검색했을 때 뜨는 인기 매물 리스트를 크롤링한 소스 코드이다. 특정 동네를 검색하는 과정을 코드에 포함하지 않고 이미 검색된 페이지를 크롤링하는 것이기 때문에 정적 크롤링으로 분류된다. 주석과 함께 살펴보자.

 

Step 1. 필요한 모듈 import

# HTTP 요청을 보내고 응답을 받는 기능을 사용하기 위한 import
import requests

# 웹 페이지에서 필요한 정보를 쉽게 가져오기 위한 import  
from bs4 import BeautifulSoup as bs

# 데이터를 구조화하고 처리하는 데 사용하기 위한 import
import pandas as pd

 

Step 2. 원하는 url로 접속

# url 주소 (당근마켓 중고거래 페이지 '강서구'검색 시 주소)
url = 'https://www.daangn.com/search/%EA%B0%95%EC%84%9C%EA%B5%AC/'

# 해당 URL에 HTTP 요청을 보내고, 변수 response에 응답을 저장
response = requests.get(url)

 

Step 3. 웹페이지에서 가져온 HTML문서 파싱

# response 객체의 내용을 HTML 파싱하여 soup 객체로 만든 후 출력
soup = bs(response.content, 'html.parser')
print(soup)

 

Step 4. 크롤링할 페이지 찾기

getItem = soup.select("#result > div > div > article")
print(getItem[0])

 

여기서 "#result > div > div > article" 는 크롬 브라우저의 개발자 도구에서 Copy selector를 통해 해당 페이지 주소를 select하는 것이다.

 

Step 5. 페이지의 모든 행 찾기

# 빈 리스트 생성
result_list = []

for item in getItem:
    # 각 요소를 추출하여 변수에 저장
    title = item.select('a > div.article-info > div.article-title-content > span.article-title')[0].text.strip()
    content = item.select('a > div.article-info > div.article-title-content > span.article-content')[0].text.strip()
    region = item.select('a > div.article-info > p.article-region-name')[0].text.strip()
    price = item.select('a > div.article-info > p.article-price')[0].text.strip().replace(' ', '').replace('\n', '').replace('∙', ',')

    # 각 요소를 리스트에 추가
    result_list.append([title, content, region, price])

# 데이터프레임으로 변환
df = pd.DataFrame(result_list, columns=['Title', 'Content', 'Region', 'Price'])

# 데이터프레임을 엑셀 파일로 저장
df.to_excel('당근마켓 강서구 게시글.xlsx', index=False)

 

마찬가지로 개발자 도구에서 각 항목마다 selector를 복사한 뒤 빈 리스트에 추가한다. 이후 생성된 리스트를 데이터프레임으로 변환해 csv파일이나 엑셀파일로 저장하면 크롤링된 데이터를 모아볼 수 있다.