메뉴 닫기

파이썬 BeautifulSoup과 urllib.parse.urljoin으로 안전한 링크 절대 경로 처리 방법

파이썬 BeautifulSoup과 urllib.parse.urljoin으로 안전한 링크 절대 경로 처리 방법

🔍 웹 크롤링 필수 스킬, base URL과 상대경로를 정확히 결합하는 법을 배워보세요

웹 크롤링을 하다 보면 링크가 절대경로가 아닌 상대경로로 되어 있는 경우가 많습니다.
이때 단순히 문자열을 더해버리면 잘못된 URL이 만들어지기도 하고, 예상치 못한 오류가 발생할 수도 있습니다.
실제 프로젝트에서는 이런 작은 오류 하나가 전체 데이터 수집 과정을 무너뜨릴 수 있기 때문에 올바른 URL 결합 방식은 필수 지식이라 할 수 있습니다.
특히, 뉴스 기사, 온라인 쇼핑몰, 블로그 글 등 다양한 웹페이지 구조에서 상대 링크를 절대 링크로 변환해야 제대로 된 데이터를 수집할 수 있습니다.
오늘은 많은 파이썬 개발자들이 사용하는 BeautifulSoup과 함께, 링크를 안전하게 절대경로로 바꿔주는 urllib.parse.urljoin() 함수의 활용법을 알아봅니다.

이번 글에서는 base URL과 상대경로의 차이를 먼저 짚어보고, 파이썬에서 어떤 방식으로 두 값을 합쳐야 올바른 절대경로가 되는지 살펴보겠습니다.
또한 웹 크롤링에서 자주 발생하는 오류와 이를 방지하는 방법도 함께 다루어 실무에서 바로 적용할 수 있도록 정리해드릴 예정입니다.
마지막에는 자주 묻는 질문까지 모아놓았으니, 초보자부터 중급 개발자까지 도움이 될 수 있을 거라 생각합니다.



🌐 base URL과 상대경로 이해하기

웹페이지에서 링크는 크게 두 가지 방식으로 표시됩니다.
첫 번째는 절대경로로, 도메인과 경로가 모두 포함된 완전한 URL입니다.
예를 들어 https://example.com/page/article.html과 같은 형태죠.
두 번째는 상대경로로, 현재 문서의 위치를 기준으로 이동하는 방식입니다.
대표적으로 /page/article.html 혹은 ../images/img.png 같은 링크가 이에 해당합니다.

상대경로는 웹사이트 내부 구조를 기준으로 동작하기 때문에, 웹 브라우저는 HTML 문서의 위치와 상대경로를 합쳐 최종적으로 접근 가능한 절대경로를 만듭니다.
하지만 크롤링을 할 때는 브라우저처럼 자동 변환이 되지 않기 때문에 개발자가 직접 base URL과 상대경로를 올바르게 합쳐야 합니다.
그렇지 않으면 데이터 수집 과정에서 링크 누락이나 잘못된 요청이 발생할 수 있습니다.

📌 base URL이 중요한 이유

웹사이트는 같은 서버 내에서 여러 페이지를 연결할 때 상대경로를 자주 사용합니다.
특히, 대규모 뉴스 사이트나 쇼핑몰의 상품 상세 페이지에서는 수천 개의 내부 링크가 상대경로로만 제공되는 경우도 있습니다.
이때 base URL을 기준으로 링크를 절대경로로 변환하지 않으면 외부 접근이 불가능해지고, 크롤러는 데이터 수집에 실패할 수밖에 없습니다.

  • 🌍절대경로는 도메인까지 포함된 완전한 주소
  • 📂상대경로는 현재 문서를 기준으로 이동
  • 웹 크롤링 시 반드시 base URL과 결합 필요

💬 상대경로를 절대경로로 변환하는 것은 웹 크롤러가 브라우저처럼 동작하게 만드는 핵심 과정입니다.

🛠️ urllib.parse.urljoin의 기본 원리

파이썬에서는 urllib.parse 모듈의 urljoin() 함수를 사용해 base URL과 상대경로를 결합할 수 있습니다.
이 함수는 단순한 문자열 덧붙이기가 아니라, 웹 브라우저의 동작 방식을 모방해 경로를 자동으로 계산합니다.
즉, 개발자가 일일이 디렉토리 이동 규칙을 신경 쓰지 않아도 올바른 절대경로를 반환해줍니다.

예를 들어 base URL이 https://example.com/articles/이고 상대경로가 page.html이라면, urljoin은 두 값을 결합해 https://example.com/articles/page.html을 반환합니다.
반대로 상대경로가 ../index.html이라면 상위 폴더로 이동해 https://example.com/index.html을 결과로 내놓습니다.

📌 urljoin 동작 규칙

urljoin은 단순히 문자열을 합치는 것이 아니라, 다음과 같은 규칙에 따라 결과를 반환합니다.

base URL 상대경로 결과
https://example.com/dir/ page.html https://example.com/dir/page.html
https://example.com/dir/page.html ../index.html https://example.com/index.html
https://example.com/dir/ /static/img.png https://example.com/static/img.png
CODE BLOCK
from urllib.parse import urljoin

base = "https://example.com/articles/"
link1 = "page.html"
link2 = "../index.html"

print(urljoin(base, link1))  # https://example.com/articles/page.html
print(urljoin(base, link2))  # https://example.com/index.html

이처럼 urljoin()은 다양한 상황에서 경로를 정확히 계산해 주기 때문에, 크롤링 과정에서 상대경로를 절대경로로 변환하는 가장 안전한 방법이라 할 수 있습니다.



📖 BeautifulSoup과 함께 쓰는 방법

웹 크롤링에서 가장 널리 사용되는 라이브러리 중 하나가 BeautifulSoup입니다.
이 도구는 HTML 문서를 파싱하여 원하는 태그를 손쉽게 추출할 수 있도록 도와줍니다.
하지만 추출한 링크가 상대경로일 경우, 그대로 사용하면 올바른 요청을 보낼 수 없습니다.
따라서 BeautifulSoup으로 얻은 링크에 urljoin()을 결합하는 것이 필수적입니다.

예를 들어 뉴스 사이트의 기사 목록에서 <a> 태그를 모두 추출했다고 가정해봅시다.
대부분의 경우 href 속성은 상대경로로 되어 있을 가능성이 큽니다.
이때 urljoin을 적용하면 모든 링크를 클릭 가능한 절대경로로 변환할 수 있어, 크롤러가 안정적으로 작동하게 됩니다.

📌 BeautifulSoup과 urljoin 실전 예시

CODE BLOCK
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

base_url = "https://example.com/news/"
response = requests.get(base_url)
soup = BeautifulSoup(response.text, "html.parser")

for a_tag in soup.find_all("a"):
    href = a_tag.get("href")
    absolute_url = urljoin(base_url, href)
    print(absolute_url)

위 코드에서 각 a 태그의 링크가 상대경로라 하더라도, urljoin이 base URL과 결합해 완전한 절대경로를 만들어 줍니다.
덕분에 크롤러는 실제 브라우저처럼 동작할 수 있고, 누락 없이 모든 링크를 탐색할 수 있습니다.

💡 TIP: BeautifulSoup으로 크롤링할 때는 항상 urljoin()으로 절대경로를 변환한 뒤 사용하는 습관을 들이면 안전합니다.

⚠️ 잘못된 URL 결합 시 발생하는 문제

웹 크롤링에서 가장 흔히 발생하는 오류 중 하나는 링크 결합을 잘못 처리했을 때 생깁니다.
특히 단순히 문자열을 더해 절대경로를 만든다면, 의도치 않은 잘못된 URL이 생성될 수 있습니다.
이 문제는 단순한 코드 오류를 넘어, 잘못된 페이지를 수집하거나 서버에 불필요한 요청을 보내는 결과로 이어질 수 있습니다.

예를 들어 base URL이 https://example.com/articles/일 때, 문자열 덧붙이기로 ../index.html을 처리하면 https://example.com/articles/../index.html과 같이 이상한 경로가 됩니다.
반면 urljoin()은 자동으로 상위 디렉토리를 인식해 https://example.com/index.html을 반환하므로, 크롤링 오류를 예방할 수 있습니다.

📌 잘못된 결합으로 생기는 대표적인 문제

  • 🚫존재하지 않는 경로를 요청하여 404 Not Found 발생
  • 🔄중복된 슬래시나 디렉토리 오류로 인해 중복 데이터 수집
  • 잘못된 링크 크롤링으로 인해 불필요한 서버 부하 초래
  • 📉결과적으로 데이터 정합성이 깨지고, 분석 결과가 왜곡됨

⚠️ 주의: 문자열 덧붙이기로 URL을 처리하는 것은 크롤링 안정성을 크게 떨어뜨립니다.
항상 urllib.parse.urljoin()을 활용해야 안전합니다.



💡 실무 활용 팁과 코드 예시

실무에서 BeautifulSoup과 urljoin()을 함께 사용하면 상대경로 문제를 깔끔하게 해결할 수 있습니다.
특히 다수의 링크를 처리할 때는 단순히 URL을 추출하는 것에 그치지 않고, 반드시 절대경로 변환 단계를 거쳐야 크롤링 결과를 신뢰할 수 있습니다.

또한 수집 과정에서 중복된 링크나 외부 링크가 섞일 수 있는데, 이를 걸러내기 위해 조건문을 함께 사용하는 것이 좋습니다.
예를 들어 특정 도메인으로 시작하는 링크만 수집하거나, 이미지 및 다운로드 링크를 제외하는 방식으로 데이터 품질을 높일 수 있습니다.

📌 크롤링 품질을 높이는 실전 코드

CODE BLOCK
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

base_url = "https://example.com/blog/"
response = requests.get(base_url)
soup = BeautifulSoup(response.text, "html.parser")

valid_links = []
for a in soup.find_all("a", href=True):
    absolute = urljoin(base_url, a["href"])
    # 특정 도메인 필터링
    if absolute.startswith(base_url):
        valid_links.append(absolute)

print(valid_links)

위 예시에서는 urljoin()을 활용해 모든 상대경로를 절대경로로 변환한 후, 해당 도메인으로 시작하는 링크만 수집하도록 조건을 걸었습니다.
이렇게 하면 불필요한 외부 링크를 차단하고, 크롤링한 데이터의 정확도를 높일 수 있습니다.

💎 핵심 포인트:
urljoin을 사용할 때는 반드시 base URL을 명확히 지정하고, 불필요한 링크를 필터링하는 습관을 들이면 실무에서 훨씬 안정적인 크롤러를 만들 수 있습니다.

자주 묻는 질문 (FAQ)

urljoin을 쓰지 않고 문자열을 더해도 되나요?
문자열 덧붙이기는 단순해 보이지만 디렉토리 이동 규칙을 처리하지 못해 잘못된 경로가 생길 가능성이 큽니다. urljoin을 사용하는 것이 안전합니다.
urljoin은 외부 링크도 처리할 수 있나요?
네, 외부 링크라면 그대로 반환합니다. 따라서 내부 링크와 혼합된 경우 필터링을 통해 원하는 링크만 골라내는 것이 좋습니다.
BeautifulSoup에서 href가 None인 경우는 어떻게 하나요?
일부 태그는 href 속성이 비어 있을 수 있습니다. 이 경우 urljoin을 적용하기 전에 조건문으로 None 값을 거르는 것이 필요합니다.
urljoin은 파일 다운로드 링크에도 쓸 수 있나요?
네, 이미지, PDF, ZIP 파일 등 모든 상대경로 링크를 절대경로로 변환할 수 있습니다. 이후 requests 등을 통해 정상적으로 다운로드 가능합니다.
urljoin을 사용할 때 주의할 점은 무엇인가요?
base URL 끝에 슬래시가 없는 경우 상대경로 처리 방식이 달라질 수 있습니다. 항상 올바른 base URL을 지정하는 습관이 중요합니다.
urljoin 대신 사용할 수 있는 다른 방법이 있나요?
직접 문자열을 파싱하거나 os.path.join과 같은 방식을 쓰는 경우도 있지만, 웹 URL 규칙을 정확히 반영하지 못하기 때문에 urljoin이 가장 권장됩니다.
대규모 크롤링에서 urljoin을 쓰면 성능에 영향을 주나요?
urljoin 자체는 매우 가벼운 함수라 성능 부담이 거의 없습니다. 오히려 잘못된 URL 요청을 줄여 전체 크롤링 효율을 높여줍니다.
urljoin은 Python 외 다른 언어에도 있나요?
네, JavaScript, Java 등 다른 언어에도 유사한 URL 처리 라이브러리가 존재합니다. 하지만 Python의 urljoin은 간결하고 직관적이라는 장점이 있습니다.

📝 BeautifulSoup과 urljoin을 활용한 안정적인 크롤링 정리

웹 크롤링에서 상대경로 문제는 초보자뿐 아니라 경험이 많은 개발자에게도 흔히 발생하는 함정입니다.
이 글에서는 base URL과 상대경로의 개념을 짚고, 파이썬에서 제공하는 urllib.parse.urljoin()을 이용해 이를 안전하게 절대경로로 변환하는 방법을 살펴보았습니다.
특히 BeautifulSoup과 함께 사용할 때 urljoin이 얼마나 중요한 역할을 하는지 코드 예시와 함께 정리했습니다.

urljoin은 단순한 문자열 결합이 아닌, 브라우저와 동일한 방식으로 경로를 해석해 올바른 결과를 반환합니다.
따라서 잘못된 URL 요청을 방지하고, 데이터 수집의 정확도를 크게 높여줍니다.
또한 실무에서는 도메인 필터링, 외부 링크 차단 등과 함께 사용하여 크롤러의 품질을 개선할 수 있습니다.

결론적으로, 안정적인 웹 크롤링을 위해서는 링크 처리 과정에서 urllib.parse.urljoin()을 적극 활용하는 것이 필수입니다.
이 습관 하나만으로도 크롤링 오류를 크게 줄이고, 더 정확한 데이터를 확보할 수 있습니다.


🏷️ 관련 태그 : 파이썬웹크롤링, BeautifulSoup, urllib, urljoin, 웹스크래핑, 데이터수집, 크롤링팁, 상대경로처리, 절대경로, 파이썬기초