웹 스크래핑 마스터: Beautiful Soup과 Scrapy 활용법 🕸️🔍
웹 스크래핑은 현대 데이터 분석과 프로그래밍 세계에서 필수적인 기술로 자리 잡았습니다. 특히 Python을 이용한 웹 스크래핑은 그 효율성과 간편함으로 인해 많은 개발자들의 사랑을 받고 있죠. 이 글에서는 웹 스크래핑의 두 강력한 도구인 Beautiful Soup과 Scrapy에 대해 깊이 있게 알아보겠습니다.
웹 스크래핑은 단순히 데이터를 수집하는 것을 넘어, 비즈니스 인텔리전스, 시장 분석, 연구 등 다양한 분야에서 활용되고 있습니다. 재능넷과 같은 플랫폼에서도 트렌드 분석이나 사용자 행동 패턴 연구를 위해 웹 스크래핑 기술을 활용할 수 있겠죠. 이제 본격적으로 Beautiful Soup과 Scrapy의 세계로 들어가 봅시다! 🚀
1. Beautiful Soup: 웹 스크래핑의 시작 🥣
Beautiful Soup은 HTML과 XML 파일에서 데이터를 추출하는 Python 라이브러리입니다. 이름에서 느껴지듯이, 복잡한 웹 페이지 구조를 '맛있는 스프' 처럼 부드럽게 파싱해주는 도구입니다.
1.1 Beautiful Soup 설치하기
Beautiful Soup을 사용하기 위해서는 먼저 설치가 필요합니다. pip를 이용해 간단히 설치할 수 있습니다:
pip install beautifulsoup4
추가로, 웹 페이지를 가져오기 위한 requests 라이브러리도 필요합니다:
pip install requests
1.2 Beautiful Soup 기본 사용법
Beautiful Soup의 기본적인 사용법을 알아보겠습니다. 아래는 간단한 예제 코드입니다:
import requests
from bs4 import BeautifulSoup
# 웹 페이지 가져오기
url = "https://example.com"
response = requests.get(url)
# BeautifulSoup 객체 생성
soup = BeautifulSoup(response.text, 'html.parser')
# 원하는 요소 찾기
title = soup.find('h1').text
paragraphs = soup.find_all('p')
print(f"제목: {title}")
for p in paragraphs:
print(p.text)
이 코드는 웹 페이지의 제목(h1 태그)과 모든 단락(p 태그)을 추출합니다.
1.3 Beautiful Soup의 주요 메서드
Beautiful Soup은 다양한 메서드를 제공하여 HTML 구조를 탐색하고 데이터를 추출할 수 있게 해줍니다. 주요 메서드들을 살펴보겠습니다:
- find(): 조건에 맞는 첫 번째 태그를 찾습니다.
- find_all(): 조건에 맞는 모든 태그를 리스트로 반환합니다.
- select(): CSS 선택자를 사용하여 태그를 찾습니다.
- get_text(): 태그 내의 텍스트만 추출합니다.
이러한 메서드들을 활용하면 복잡한 웹 페이지에서도 원하는 데이터를 쉽게 추출할 수 있습니다.
1.4 고급 Beautiful Soup 테크닉
Beautiful Soup을 더 효과적으로 사용하기 위한 몇 가지 고급 테크닉을 소개합니다:
- 정규 표현식 사용: re 모듈과 함께 사용하여 더 복잡한 패턴의 데이터를 추출할 수 있습니다.
- CSS 선택자 활용: select() 메서드를 사용하여 CSS 선택자로 요소를 찾을 수 있습니다.
- 속성 필터링: 태그의 특정 속성값을 기준으로 요소를 찾을 수 있습니다.
예를 들어, 다음과 같이 사용할 수 있습니다:
# 정규 표현식 사용
import re
emails = soup.find_all(string=re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'))
# CSS 선택자 활용
blue_links = soup.select('a.blue')
# 속성 필터링
data_items = soup.find_all('div', attrs={'data-type': 'product'})
이러한 고급 테크닉을 활용하면 더 정교하고 효율적인 웹 스크래핑이 가능해집니다.
1.5 Beautiful Soup의 장단점
Beautiful Soup은 많은 장점을 가지고 있지만, 몇 가지 단점도 있습니다. 이를 표로 정리해보겠습니다:
장점
- 사용하기 쉽고 직관적임
- HTML 구조를 쉽게 탐색할 수 있음
- 강력한 파싱 기능
- 다양한 파서 지원 (lxml, html5lib 등)
단점
- 대규모 웹 크롤링에는 적합하지 않음
- JavaScript로 렌더링되는 콘텐츠 처리 어려움
- 동적 웹사이트 처리에 제한적
- 병렬 처리 기능 없음
Beautiful Soup은 특히 정적인 웹 페이지에서 데이터를 추출하는 데 탁월한 성능을 보입니다. 하지만 대규모 크롤링이나 동적 웹사이트 처리에는 한계가 있어, 이런 경우에는 Scrapy와 같은 더 강력한 도구를 고려해볼 수 있습니다.
1.6 Beautiful Soup 실전 예제
실제 웹사이트에서 데이터를 추출하는 예제를 통해 Beautiful Soup의 활용법을 더 자세히 알아보겠습니다. 이번에는 가상의 도서 리뷰 사이트에서 책 정보를 추출하는 코드를 작성해보겠습니다.
import requests
from bs4 import BeautifulSoup
url = "https://example-bookstore.com/bestsellers"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
books = soup.find_all('div', class_='book-item')
for book in books:
title = book.find('h2', class_='book-title').text.strip()
author = book.find('span', class_='book-author').text.strip()
price = book.find('span', class_='book-price').text.strip()
rating = book.find('div', class_='book-rating')['data-rating']
print(f"제목: {title}")
print(f"저자: {author}")
print(f"가격: {price}")
print(f"평점: {rating}")
print("-" * 50)
이 코드는 가상의 베스트셀러 페이지에서 각 책의 제목, 저자, 가격, 평점을 추출합니다. 실제 웹사이트의 구조에 따라 클래스 이름이나 태그는 다를 수 있습니다.
1.7 Beautiful Soup 성능 최적화 팁
Beautiful Soup을 사용할 때 성능을 최적화하기 위한 몇 가지 팁을 소개합니다:
- 적절한 파서 선택: 'lxml' 파서가 일반적으로 가장 빠르지만, 설치가 필요합니다.
- 필요한 부분만 파싱: 전체 페이지가 아닌 필요한 부분만 BeautifulSoup 객체로 만듭니다.
- CSS 선택자 활용: find() 메서드보다 select() 메서드가 더 빠를 수 있습니다.
- 제너레이터 사용: 대량의 데이터를 처리할 때는 제너레이터를 활용하여 메모리 사용을 최적화합니다.
이러한 최적화 기법을 적용하면 Beautiful Soup의 성능을 상당히 향상시킬 수 있습니다.
2. Scrapy: 강력한 웹 크롤링 프레임워크 🕷️
Scrapy는 Python으로 작성된 오픈 소스 웹 크롤링 프레임워크입니다. Beautiful Soup이 단순한 라이브러리라면, Scrapy는 완전한 애플리케이션 프레임워크로, 대규모 웹 크롤링 프로젝트에 적합합니다.
2.1 Scrapy 설치하기
Scrapy를 설치하는 방법은 다음과 같습니다:
pip install scrapy
Scrapy는 여러 의존성 패키지를 함께 설치하므로, 가상 환경을 사용하는 것이 좋습니다.
2.2 Scrapy 프로젝트 시작하기
Scrapy 프로젝트를 시작하는 방법은 다음과 같습니다:
scrapy startproject myproject
cd myproject
scrapy genspider example example.com
이 명령어들은 Scrapy 프로젝트의 기본 구조를 생성하고, 'example.com'을 크롤링하기 위한 기본 스파이더를 만듭니다.
2.3 Scrapy의 주요 컴포넌트
Scrapy는 여러 컴포넌트로 구성되어 있습니다. 각 컴포넌트의 역할을 이해하는 것이 중요합니다:
Scrapy의 주요 컴포넌트
- Spider: 크롤링 로직을 정의하는 클래스
- Engine: 시스템의 모든 컴포넌트 사이의 데이터 흐름을 제어
- Scheduler: 엔진에서 받은 요청을 큐에 저장하고 관리
- Downloader: 웹 페이지를 가져와 엔진에 전달
- Item Pipeline: 스파이더가 추출한 아이템을 처리
- Middleware: 엔진, 스파이더, 다운로더 사이의 처리 과정에 훅을 제공
이러한 컴포넌트들이 유기적으로 작동하여 효율적인 웹 크롤링을 가능하게 합니다.
2.4 Scrapy Spider 작성하기
Scrapy에서 가장 중요한 부분은 Spider입니다. 다음은 간단한 Spider 예제입니다:
import scrapy
class BookSpider(scrapy.Spider):
name = 'bookspider'
start_urls = ['https://example-bookstore.com/bestsellers']
def parse(self, response):
for book in response.css('div.book-item'):
yield {
'title': book.css('h2.book-title::text').get().strip(),
'author': book.css('span.book-author::text').get().strip(),
'price': book.css('span.book-price::text').get().strip(),
'rating': book.css('div.book-rating::attr(data-rating)').get()
}
next_page = response.css('a.next-page::attr(href)').get()
if next_page is not None:
yield response.follow(next_page, self.parse)
이 Spider는 앞서 Beautiful Soup 예제에서 다룬 것과 같은 도서 정보를 추출하지만, 페이지네이션도 처리합니다.
2.5 Scrapy의 고급 기능
Scrapy는 다양한 고급 기능을 제공합니다:
- 미들웨어: 요청과 응답을 수정하거나 필터링할 수 있습니다.
- 아이템 파이프라인: 추출된 데이터를 정제하고 저장하는 과정을 관리합니다.
- 동시성 처리: 기본적으로 비동기 처리를 지원하여 높은 성능을 제공합니다.
- User-Agent 로테이션: IP 차단을 방지하기 위해 User-Agent를 자동으로 변경할 수 있습니다.
이러한 고급 기능들을 활용하면 더욱 강력하고 효율적인 웹 크롤러를 구축할 수 있습니다.
2.6 Scrapy vs Beautiful Soup
Scrapy와 Beautiful Soup은 각각의 장단점이 있습니다. 두 도구를 비교해보겠습니다:
Scrapy
장점:
- 대규모 크롤링에 적합
- 비동기 처리로 높은 성능
- 내장된 미들웨어와 파이프라인
- 확장성이 뛰어남
단점:
- 학습 곡선이 가파름
- 간단한 작업에는 과도할 수 있음
Beautiful Soup
장점:
- 사용하기 쉽고 직관적
- 빠르게 프로토타입 제작 가능
- HTML 파싱에 특화됨
단점:
- 대규모 크롤링에는 부적합
- 비동기 처리 지원 안 함
- 추가 기능 구현 필요
프로젝트의 규모와 복잡성, 그리고 개발자의 경험 수준에 따라 적절한 도구를 선택해야 합니다.
2.7 Scrapy 실전 예제: 뉴스 기사 크롤링
이번에는 Scrapy를 사용하여 뉴스 웹사이트에서 기사를 크롤링하는 예제를 살펴보겠습니다.
import scrapy
class NewsSpider(scrapy.Spider):
name = 'newsspider'
start_urls = ['https://example-news.com/latest']
def parse(self, response):
for article in response.css('div.article-item'):
yield {
'title': article.css('h2.article-title::text').get().strip(),
'author': article.css('span.article-author::text').get().strip(),
'date': article.css('span.article-date::text').get().strip(),
'summary': article.css('p.article-summary::text').get().strip(),
'url': article.css('a.article-link::attr(href)').get()
}
# 기사 상세 페이지로 이동
article_url = article.css('a.article-link::attr(href)').get()
yield response.follow(article_url, self.parse_article)
# 다음 페이지로 이동
next_page = response.css('a.next-page::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)
def parse_article(self, response):
yield {
'url': response.url,
'title': response.css('h1.article-title::text').get().strip(),
'content': ' '.join(response.css('div.article-content p::text').getall()).strip(),
'tags': response.css('div.article-tags a::text').getall()
}
이 Spider는 뉴스 목록 페이지에서 기사의 기본 정보를 추출하고, 각 기사의 상세 페이지로 이동하여 전체 내용과 태그를 크롤링합니다.
2.8 Scrapy 성능 최적화 팁
Scrapy의 성능을 최적화하기 위한 몇 가지 팁을 소개합니다:
- 동시성 조절: CONCURRENT_REQUESTS 설정을 조정하여 동시 요청 수를 최적화합니다.
- 캐싱 활용: HTTP 캐시를 사용하여 중복 요청을 줄입니다.
- Item Loader 사용: 데이터 추출과 처리를 분리하여 코드를 깔끔하게 유지합니다.
- 미들웨어 최적화: 불필요한 미들웨어를 비활성화하여 오버헤드를 줄입니다.
이러한 최적화 기법을 적용하면 Scrapy의 성능을 크게 향상시킬 수 있습니다.
3. 웹 스크래핑 윤리와 법적 고려사항 ⚖️
웹 스크래핑은 강력한 도구이지만, 윤리적이고 법적인 문제를 고려해야 합니다. 무분별한 스크래핑은 웹사이트 소유자의 권리를 침해하거나 법적 문제를 야기할 수 있습니다.
3.1 robots.txt 준수
대부분의 웹사이트는 robots.txt 파일을 통해 크롤러의 접근 규칙을 명시합니다. 이를 반드시 준수해야 합니다.
from urllib.robotparser import RobotFileParser
def is_allowed(url):
rp = RobotFileParser()
rp.set_url(url + "/robots.txt")
rp.read()
return rp.can_fetch("*", url)
이 함수를 사용하여 URL에 대한 크롤링 허용 여부를 확인할 수 있습니다.
3.2 적절한 크롤링 속도 유지
서버에 과도한 부하를 주지 않도록 적절한 크롤링 속도를 유지해야 합니다. Scrapy에서는 DOWNLOAD_DELAY 설정을 통해 요청 간 간격을 조절할 수 있습니다.
3.3 개인정보 보호
크롤링 과정에서 개인정보를 수집하게 될 경우, 관련 법규를 준수해야 합니다. 필요 이상의 개인정보를 수집하지 않도록 주의해야 합니다.
3.4 저작권 존중
웹사이트의 콘텐츠는 대부분 저작권으로 보호됩니다. 무단으로 콘텐츠를 복제하거나 재배포하는 것은 법적 문제를 야기할 수 있습니다.
웹 스크래핑 시 주의사항
- 웹사이트의 이용약관을 확인하세요.
- 필요한 데이터만 수집하세요.
- 서버에 과도한 부하를 주지 마세요.
- 수집한 데이터의 사용 목적을 명확히 하세요.
- 가능하다면 웹사이트 소유자의 허가를 받으세요.
웹 스크래핑을 윤리적이고 책임감 있게 수행함으로써, 데이터의 가치를 극대화하면서도 법적 문제를 예방할 수 있습니다.
4. 웹 스크래핑의 실제 응용 사례 🌐
웹 스크래핑은 다양한 분야에서 활용되고 있습니다. 몇 가지 실제 응용 사례를 살펴보겠습니다.
4.1 가격 비교 서비스
여러 쇼핑몰의 상품 가격을 수집하여 비교하는 서비스를 만들 수 있습니다. 이는 소비자들에게 유용한 정보를 제공합니다.
4.2 부동산 시장 분석
부동산 웹사이트에서 매물 정보를 수집하여 시장 동향을 분석할 수 있습니다. 이는 투자자나 정책 입안자들에게 중요한 인사이트를 제공할 수 있습니다.
4.3 구직 정보 수집
여러 구인구직 사이트에서 채용 정보를 수집하여 통합 job 검색 서비스를 제공할 수 있습니다.
4.4 소셜 미디어 분석
소셜 미디어 플랫폼에서 데이터를 수집하여 브랜드 평판이나 트렌드를 분석할 수 있습니다.
4.5 학술 연구
연구자들은 웹 스크래핑을 통해 대량의 데이터를 수집하여 다양한 학술 연구에 활용할 수 있습니 다.
4.6 뉴스 및 미디어 모니터링
다양한 뉴스 사이트에서 기사를 수집하여 특정 주제나 키워드에 대한 미디어 동향을 분석할 수 있습니다. 이는 기업의 PR 전략이나 정부의 정책 결정에 중요한 인사이트를 제공할 수 있습니다.
4.7 경쟁사 모니터링
경쟁 기업의 웹사이트에서 제품 정보, 가격, 프로모션 등을 주기적으로 수집하여 시장 동향을 파악하고 경쟁 전략을 수립하는 데 활용할 수 있습니다.
4.8 재능넷 플랫폼에서의 활용
재능넷과 같은 프리랜서 플랫폼에서도 웹 스크래핑을 다양하게 활용할 수 있습니다:
- 수요 트렌드 분석: 가장 많이 요청되는 서비스 카테고리나 키워드를 파악하여 플랫폼 운영 전략 수립
- 가격 동향 모니터링: 각 서비스 카테고리별 평균 가격 추이를 분석하여 적정 가격 가이드 제공
- 사용자 피드백 분석: 리뷰 데이터를 수집하여 서비스 품질 개선 및 사용자 만족도 향상
- 경쟁 플랫폼 모니터링: 타 플랫폼의 서비스 구조나 가격 정책을 분석하여 경쟁력 강화
재능넷에서의 웹 스크래핑 활용 예시
재능넷에서 가장 인기 있는 서비스 카테고리를 파악하기 위한 간단한 Scrapy 스파이더 예시:
import scrapy
class TalentnetSpider(scrapy.Spider):
name = 'talentnet'
start_urls = ['https://www.talentnet.com/categories']
def parse(self, response):
for category in response.css('div.category-item'):
yield {
'name': category.css('h3::text').get().strip(),
'service_count': category.css('span.service-count::text').get().strip(),
'average_rating': category.css('span.avg-rating::text').get().strip()
}
next_page = response.css('a.next-page::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)
이러한 데이터 수집과 분석을 통해 재능넷은 플랫폼의 서비스 품질을 개선하고 사용자 경험을 향상시킬 수 있습니다.
5. 웹 스크래핑의 미래와 발전 방향 🚀
웹 스크래핑 기술은 계속해서 발전하고 있으며, 미래에는 더욱 중요한 역할을 할 것으로 예상됩니다. 몇 가지 주요 트렌드와 발전 방향을 살펴보겠습니다.
5.1 AI와 머신러닝의 통합
인공지능과 머신러닝 기술이 웹 스크래핑과 결합되면서, 더욱 지능적이고 효율적인 데이터 수집이 가능해질 것입니다. 예를 들어:
- 자동 패턴 인식: AI가 웹사이트의 구조를 자동으로 분석하고 최적의 스크래핑 방법을 제안
- 콘텐츠 분류 및 요약: 수집된 데이터를 자동으로 분류하고 중요 정보를 요약
- 예측적 스크래핑: 과거 데이터 패턴을 기반으로 미래의 데이터 변화를 예측하고 선제적으로 수집
5.2 실시간 데이터 처리
실시간 데이터의 중요성이 증가함에 따라, 웹 스크래핑도 실시간 처리 능력을 강화할 것입니다:
- 스트리밍 데이터 수집: 소셜 미디어 피드나 주식 시장 데이터와 같은 실시간 정보를 지속적으로 수집
- 실시간 분석 및 알림: 수집된 데이터를 즉시 분석하여 중요한 변화나 트렌드를 감지하고 알림
5.3 분산 및 클라우드 기반 스크래핑
대규모 데이터 수집을 위해 분산 컴퓨팅과 클라우드 기술이 더욱 중요해질 것입니다:
- 클라우드 스크래핑 서비스: 필요에 따라 확장 가능한 클라우드 기반의 스크래핑 인프라 제공
- 분산 크롤링: 여러 서버에서 동시에 크롤링을 수행하여 효율성 극대화
5.4 윤리적 스크래핑 도구
웹사이트 소유자의 권리를 존중하면서도 효과적인 데이터 수집이 가능한 윤리적 스크래핑 도구가 발전할 것입니다:
- 자동 규정 준수: robots.txt와 웹사이트 정책을 자동으로 해석하고 준수하는 스크래퍼
- 투명성 강화: 데이터 수집 목적과 방법을 명확히 공개하는 기능 탑재
5.5 IoT와의 통합
사물인터넷(IoT) 기기의 증가로, 웹 스크래핑은 물리적 세계의 데이터도 수집하게 될 것입니다:
- 센서 데이터 수집: IoT 기기에서 생성되는 데이터를 실시간으로 수집 및 분석
- 스마트 시티 모니터링: 도시 인프라의 다양한 데이터를 수집하여 도시 관리에 활용
미래의 웹 스크래핑 시나리오
2030년, 한 데이터 분석가가 글로벌 시장 동향을 파악하기 위해 AI 기반 스크래핑 플랫폼을 사용합니다:
- AI가 자동으로 관련 웹사이트들을 식별하고 최적의 스크래핑 전략을 수립합니다.
- 분산 클라우드 시스템이 전 세계의 데이터를 실시간으로 수집합니다.
- 머신러닝 알고리즘이 수집된 데이터를 즉시 분석하여 주요 트렌드와 인사이트를 추출합니다.
- IoT 센서 데이터와 웹 데이터가 통합되어 더욱 포괄적인 시장 분석이 가능해집니다.
- 모든 과정이 윤리적 가이드라인을 준수하며, 데이터 사용에 대한 투명성이 보장됩니다.
이러한 발전은 웹 스크래핑을 더욱 강력하고 유용한 도구로 만들 것이며, 데이터 기반 의사결정의 핵심 요소로 자리잡게 될 것입니다.
6. 결론 및 제언 🎯
웹 스크래핑은 디지털 시대의 필수적인 기술로 자리잡았습니다. Beautiful Soup과 Scrapy는 각각의 장점을 가진 강력한 도구로, 프로젝트의 규모와 복잡성에 따라 적절히 선택하여 사용할 수 있습니다.
6.1 Beautiful Soup vs Scrapy: 언제 무엇을 선택할까?
- Beautiful Soup: 간단한 프로젝트, 빠른 프로토타이핑, HTML 파싱에 중점을 둔 작업에 적합
- Scrapy: 대규모 프로젝트, 복잡한 크롤링 로직, 고성능이 요구되는 작업에 적합
6.2 웹 스크래핑의 미래 준비
웹 스크래핑 기술의 발전에 발맞추어 다음과 같은 준비를 할 수 있습니다:
- AI와 머신러닝 학습: 데이터 분석과 자동화 능력 향상
- 클라우드 컴퓨팅 이해: 대규모 분산 시스템 활용 능력 개발
- 데이터 윤리와 법규 숙지: 책임 있는 데이터 수집 및 활용
- API 및 데이터 통합 기술 습득: 다양한 데이터 소스 활용 능력 강화
6.3 재능넷 플랫폼에서의 웹 스크래핑 활용 전략
재능넷과 같은 플랫폼에서 웹 스크래핑을 효과적으로 활용하기 위한 전략을 제안합니다:
재능넷 웹 스크래핑 활용 전략
- 시장 동향 분석: 경쟁 플랫폼의 서비스 트렌드를 주기적으로 분석
- 사용자 피드백 수집: 리뷰 데이터를 수집하여 서비스 품질 개선에 활용
- 가격 정책 최적화: 시장 가격 동향을 분석하여 경쟁력 있는 가격 정책 수립
- 인재 발굴: 다양한 플랫폼에서 우수 인재 정보를 수집하여 유치 전략 수립
- 콘텐츠 전략 수립: 인기 있는 서비스 카테고리와 키워드를 분석하여 마케팅 전략에 반영
6.4 마무리
웹 스크래핑은 강력한 도구이지만, 책임감 있게 사용해야 합니다. 데이터의 가치를 인식하고 윤리적으로 활용함으로써, 비즈니스와 사회에 긍정적인 영향을 미칠 수 있습니다. Beautiful Soup과 Scrapy를 마스터하고, 끊임없이 발전하는 기술 트렌드를 따라가며, 데이터의 힘을 최대한 활용하시기 바랍니다.
웹 스크래핑의 세계는 무궁무진한 가능성으로 가득 차 있습니다. 이 기술을 통해 새로운 인사이트를 발견하고, 혁신적인 서비스를 개발하며, 데이터 기반의 의사결정을 내리는 여정을 즐기시기 바랍니다. 항상 윤리적 가이드라인을 준수하면서, 창의적이고 생산적인 방식으로 웹 스크래핑을 활용해 나가세요. 여러분의 노력이 디지털 세상을 더욱 풍요롭게 만들 것입니다. 화이팅! 🚀📊🌐