이 글에서는 Python으로 Booking.com 웹사이트에서 데이터를 수집하는 방법을 보여드리겠습니다. 호텔 이름, 평점, 가격, 위치 주소 및 설명을 포함하되 이에 국한되지 않는 정보를 얻을 수 있습니다. 제공된 코드를 사용하면 HTML 콘텐츠를 구문 분석하고 임베드된 JSON 데이터를 추출하여 호텔 페이지에서 데이터를 검색할 수 있습니다.
Booking.com에서 데이터를 스크랩하는 코드를 실행하기 전에 필요한 Python 라이브러리를 설치해야 합니다. 필요한 종속성을 설치하는 방법은 다음과 같습니다:
필요한 라이브러리를 설치하려면 pip를 사용할 수 있습니다:
pip install requests lxml
이것들은 필요한 유일한 외부 라이브러리이며, 나머지 라이브러리(json, csv)는 Python과 함께 사전 설치되어 제공됩니다.
Booking.com에서 데이터를 스크랩할 때는 웹 페이지의 구조와 추출하려는 데이터의 종류를 이해하는 것이 중요합니다. Booking.com의 각 호텔 페이지에는 이름, 위치, 가격과 같은 세부 정보를 쉽게 추출할 수 있는 JSON-LD 형식의 구조화된 데이터가 내장되어 있습니다. 이 데이터를 스크랩하겠습니다.
Booking.com은 동적 사이트이며 자동화된 작업을 방지하기 위한 조치를 구현하고 있으므로 차단 위험 없이 원활한 스크래핑을 위해 적절한 HTTP 헤더와 프록시를 사용할 것입니다.
헤더는 브라우저에서 사용자 세션을 모방하여 Booking.com의 스크래핑 방지 시스템에서 감지되지 않도록 합니다. 헤더를 올바르게 구성하지 않으면 서버가 자동화된 스크립트를 쉽게 식별할 수 있으며, 이로 인해 IP 차단이나 보안 문자 문제가 발생할 수 있습니다.
Booking.com의 스크래핑 방지 메커니즘에 의해 차단되는 것을 방지하기 위해 사용자 지정 헤더를 사용하여 정상적인 사용자가 웹사이트를 탐색하는 것처럼 시뮬레이션합니다. 적절한 헤더를 사용하여 HTTP 요청을 보내는 방법은 다음과 같습니다:
import requests
from lxml.html import fromstring
urls_list = ["https links"]
for url in urls_list:
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'accept-language': 'en-IN,en;q=0.9',
'cache-control': 'no-cache',
'dnt': '1',
'pragma': 'no-cache',
'priority': 'u=0, i',
'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Linux"',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
}
response = requests.get(url, headers=headers)
Booking.com과 같이 엄격한 요청 속도 제한을 적용하거나 IP 주소를 추적하는 사이트를 스크래핑할 때는 프록시를 사용해야 합니다. 프록시는 여러 IP 주소에 요청 부하를 분산시켜 차단을 방지합니다. 이를 위해 무료 프록시와 사용자 이름과 비밀번호 또는 IP 주소로 인증하는 유료 프록시 서비스를 모두 사용할 수 있습니다. 이 예에서는 후자의 옵션을 사용합니다.
proxies = {
'http': '',
'https': ''
}
response = requests.get(url, headers=headers, proxies=proxies)
요청을 전송한 후 lxml을 사용하여 HTML 콘텐츠를 구문 분석하여 호텔 세부 정보가 포함된 임베디드 JSON-LD 데이터를 찾습니다. 이 단계에서는 웹 페이지에서 호텔 이름, 가격, 위치 등이 포함된 구조화된 데이터를 추출합니다.
parser = fromstring(response.text)
# 임베디드 JSON 데이터 추출
embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
json_data = json.loads(embeded_jsons[0])
파싱된 JSON 데이터를 확보하면 호텔 이름, 주소, 등급, 가격 등 관련 필드를 추출할 수 있습니다. 다음은 JSON에서 호텔 정보를 추출하는 코드입니다:
name = json_data['name']
location = json_data['hasMap']
priceRange = json_data['priceRange']
description = json_data['description']
url = json_data['url']
ratingValue = json_data['aggregateRating']['ratingValue']
reviewCount = json_data['aggregateRating']['reviewCount']
type_ = json_data['@type']
postalCode = json_data['address']['postalCode']
addressLocality = json_data['address']['addressLocality']
addressCountry = json_data['address']['addressCountry']
addressRegion = json_data['address']['addressRegion']
streetAddress = json_data['address']['streetAddress']
image_url = json_data['image']
room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")
# all_data 목록에 데이터 추가
all_data.append({
"Name": name,
"Location": location,
"Price Range": priceRange,
"Rating": ratingValue,
"Review Count": reviewCount,
"Type": type_,
"Postal Code": postalCode,
"Address Locality": addressLocality,
"Country": addressCountry,
"Region": addressRegion,
"Street Address": streetAddress,
"URL": url,
"Image URL": image_url,
"Room Types": room_types
})
데이터를 추출한 후에는 추가 분석을 위해 CSV 파일로 저장할 수 있습니다:
# 모든 URL이 처리된 후 데이터를 CSV 파일에 기록합니다.
with open('booking_data.csv', 'w', newline='') as csvfile:
fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code",
"Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
# 헤더 작성
writer.writeheader()
# 데이터 행 쓰기
writer.writerows(all_data)
다음은 모든 섹션을 결합한 전체 코드입니다:
import requests
from lxml.html import fromstring
import json
import csv
# 스크랩할 호텔 URL 목록
urls_list = [
"Https link",
"Https link"
]
# 모든 스크랩된 데이터를 저장할 빈 목록을 초기화합니다.
all_data = []
proxies = {
'http': ''
}
# 각 URL을 반복하여 데이터 스크랩
for url in urls_list:
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'accept-language': 'en-IN,en;q=0.9',
'cache-control': 'no-cache',
'dnt': '1',
'pragma': 'no-cache',
'priority': 'u=0, i',
'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Linux"',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
}
# 웹사이트로 요청 보내기
response = requests.get(url, headers=headers, proxies=proxies)
# HTML 콘텐츠 구문 분석하기
parser = fromstring(response.text)
# 임베디드 JSON 데이터 추출
embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
json_data = json.loads(embeded_jsons[0])
# JSON에서 모든 호텔 세부 정보 추출
name = json_data['name']
location = json_data['hasMap']
priceRange = json_data['priceRange']
description = json_data['description']
url = json_data['url']
ratingValue = json_data['aggregateRating']['ratingValue']
reviewCount = json_data['aggregateRating']['reviewCount']
type_ = json_data['@type']
postalCode = json_data['address']['postalCode']
addressLocality = json_data['address']['addressLocality']
addressCountry = json_data['address']['addressCountry']
addressRegion = json_data['address']['addressRegion']
streetAddress = json_data['address']['streetAddress']
image_url = json_data['image']
room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")
# all_data 목록에 데이터 추가
all_data.append({
"Name": name,
"Location": location,
"Price Range": priceRange,
"Rating": ratingValue,
"Review Count": reviewCount,
"Type": type_,
"Postal Code": postalCode,
"Address Locality": addressLocality,
"Country": addressCountry,
"Region": addressRegion,
"Street Address": streetAddress,
"URL": url,
"Image URL": image_url,
"Room Types": room_types
})
# 모든 URL이 처리된 후 데이터를 CSV 파일에 기록합니다.
with open('booking_data.csv', 'w', newline='') as csvfile:
fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code",
"Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
# 헤더 작성
writer.writeheader()
# 데이터 행 쓰기
writer.writerows(all_data)
print("Data successfully saved to booking_data.csv")
이 글에서는 파이썬을 사용해 Booking.com에서 호텔 데이터를 스크랩하는 방법을 설명했습니다. 스크래핑 방지 조치를 우회하기 위해 적절한 HTTP 헤더와 프록시를 사용하는 것이 중요하다는 점을 강조했습니다. 추출된 데이터는 추가 분석을 위해 CSV 파일로 저장할 수 있습니다. 웹사이트를 스크래핑할 때는 항상 서비스 약관을 확인하여 위반하지 않도록 주의하세요.
댓글: 0