about
hotels-scraper-js
是一个node.js软件包,旨在从单个模块中解析流行网站酒店。
软件包是available on npm,可以在您的Node.js项目中安装和使用。它用于从Airbnb,Booking和Hotels.com网站上刮擦酒店清单和酒店信息。很快,我们计划添加Google Hotels或其他网站。
该项目的长期计划是将API和非API解决方案与SerpApi started developing support for Google Hotels相结合,以便后来的用户可以选择所需的后端可以使用(免费限制或付款而无需限制)。 Serpapi的后端对于那些不知道如何使用它的人也可能有用,例如,可以使用简单函数的pagination=True
启用serpapi分页。
开发由SerpApi。
赞助限制和问题
-
主要问题是解析的站点经常更改其结构或选择器,因此不时无法获得刮擦字段之一(有时解析器可能会崩溃)。
li> -
hotels.com有时不会加载位置输入字段(通常在通常的浏览器中发生),并且该位置自动填充不起作用,因此解析器可能会崩溃。
-
如果您的IP地址被阻止,或者您的国家无法访问您的IP地址,并且如果该解析器中的一个网站在您的浏览器中不起作用,则无法从此解析器中获得结果。 p>
使用`hotels-scraper-js'?
可以获得什么airbnb:
按类别按类别推荐的酒店清单
通过选定位置和日期列表
选定的酒店信息
预订:
通过选定位置和日期列表
选定的酒店信息
hotels.com:
通过选定位置和日期列表
选定的酒店信息
安装&使用
您可以从documentation
获得“安装指南”和所有可用选项基本示例
在这些基本示例中,我们将从3个解析器中获得指向每个酒店的链接。然后这些链接将用于获取酒店信息。
Airbnb酒店由选定类别和选定的货币产生。
首先,我们需要获得所有可用类别和货币:
console.log(airbnb.getFilters());
输出:
{
"currencies":[
{
"name":"Australian dollar",
"value":"AUD"
},
{
"name":"Brazilian real",
"value":"BRL"
},
... and other currencies
],
"categories":[
{
"name":"A-frames",
"value":"8148"
},
{
"name":"Design",
"value":"8528"
},
... and other categories
]
}
接下来,使用50
结果的类别和货币获取酒店列表的使用:
ð注意:您可以同时使用name
或value
。
airbnb.getHotels("Design", "BRL", 50).then(console.log);
输出:
[
{
"thumbnail":"https://a0.muscache.com/im/pictures/74102172/9815f41f_original.jpg?im_w=720",
"title":"Bolzano, Italy",
"subtitles":[
"Designed by Peter Pichler",
"Apr 15 – 20"
],
"price":{
"currency":"R$",
"value":1417,
"period":"night"
},
"rating":4.8,
"link":"https://www.airbnb.com/rooms/4594196"
},
{
"thumbnail":"https://a0.muscache.com/im/pictures/397ed026-16a9-4418-af19-1d2b31fe0aa8.jpg?im_w=720",
"title":"Korčula, Croatia",
"subtitles":[
"Luxury Lifestyle Awards: Best Luxury Villa Croatia",
"Apr 1 – 6"
],
"price":{
"currency":"R$",
"value":11290,
"period":"night"
},
"rating":"No rating",
"link":"https://www.airbnb.com/luxury/listing/34594127"
},
... and other hotels
]
然后使用其中一个酒店链接获取酒店信息:
airbnb.getHotelInfo("https://www.airbnb.com/rooms/4594196").then((data) => {
console.dir(data, { depth: null });
});
输出:
{
"name":"Mirror House Sud",
"shortDescription":"Entire home hosted by Sabina Angela",
"shortOverview":[
"4 guests",
"1 bedroom",
"1 bed",
"1 bath"
],
"highlights":[
{
"title":"Designed by",
"subtitle":"Peter Pichler"
},
{
"title":"Featured in",
"subtitle":"Designboom, December 2014ArchDaily, December 2014"
},
{
"title":"Sabina Angela is a Superhost",
"subtitle":"Superhosts are experienced, highly rated hosts who are committed to providing great stays for guests."
}
],
"price":{
"currency":"₴",
"amount":8828,
"period":"night"
},
"description":"Mirror Houses are two small houses immersed in a beautiful scenery of apple orchards just outside, in the wonderful surroundings of the South Tyrolean Dolomites.The Mirror Houses offer a unique opportunity to spend a wonderful holiday surrounded by contemporary architecture of the highest standards in close contact with one of the most evocative landscapes that nature can offer.The spaceThe Mirror House Sud (45sqm) consists of 1 bedroom with double bed, 1 bathroom with spacious shower and 1 living room / kitchen (single space) with a double sofa bed. The location is ideal for 2 people, but can accommodate up to a maximum of 4 people.If you are 4 adults we recommend booking both Mirror House North and South.In addition there is a spacious terrace that + a private garden and
in the summer months a shared garden with a common pool and a self-service pool bar.Under the houses there is also a common storage room for sports equipment or other.",
"sleepOptions":[
],
"host":{
"name":"Sabina Angela",
"joined":"Joined in March 2013",
"overview":[
"127 Reviews",
"Identity verified",
"Superhost"
],
"additionalInfo":[
"Response rate: 87%",
"Response time: within an hour"
]
},
"link":"https://www.airbnb.com/rooms/4594196",
"placeOffers":[
"Hair dryer",
"Shampoo",
"Hot water",
... and other place offers
],
"houseRules":[
"4 guests maximum",
"No pets",
"Check-in: 2:00 PM - 9:00 PM",
"Checkout before 11:00 AM",
"No commercial photography",
"No parties or events",
"No smoking"
],
"safetyAndProperty":[
"Carbon monoxide alarm not reported",
"Smoke alarm not reported",
"Some spaces are shared"
],
"photos":[
"https://a0.muscache.com/im/pictures/74102421/46d207f2_original.jpg?aki_policy=large",
"https://a0.muscache.com/im/pictures/74102172/9815f41f_original.jpg?aki_policy=large",
"https://a0.muscache.com/im/pictures/309bee53-311d-4f07-a2e7-14daadbbfb77.jpg?aki_policy=large",
... and other photos
],
"reviewsInfo":{
"totalReviews":53,
"rating":{
"total":4.81,
"cleanliness":4.9,
"accuracy":4.9,
"communication":4.8,
"location":4.7,
"checkIn":4.8,
"value":4.6
},
"reviews":[
{
"name":"Nadav",
"avatar":"https://a0.muscache.com/im/pictures/user/cbecae28-d8cc-46b9-9294-c1b0fcb512e9.jpg?im_w=240",
"userPage":"https://www.airbnb.com/users/show/10949335",
"date":"March 2023",
"review":"Had an amazing time at the Mirror House. Not only was the place very beautifully designed, but the location also made it very special. A must-stay for a romantic vacation in Bolzano.
In addition to this, Sabine was probably the best host I've had while using AirBnb. She was very helpful in helping us get reservations to local restaurants and actually made us a cake (this was an engagement trip, so she offered to make us one instead of actually getting one at a bakery). Overall, we had an amazing vacation. Sabine and the Mirror House definitely made it very special for us!"
},
{
"name":"Khaled",
"avatar":"https://a0.muscache.com/im/pictures/user/f7804757-f867-46d5-8557-33d9be786657.jpg?im_w=240",
"userPage":"https://www.airbnb.com/users/show/179920339",
"date":"March 2023",
"review":"Beautiful place and private surroundingIt was a good experienceHighly recommended"
},
... and other reviews
]
}
}
预订酒店的结果,以选定的过滤器,货币,位置,日期,客人数量以及用于商业目的的设置。
首先,我们需要获取所有可用类别和货币:
ð注意:您需要使用console.dir
方法在结果对象中查看超过两个的内部键的深度。
console.dir(booking.getFilters(), { depth: null });
输出:
{
"currencies":[
{
"name":"Property's Currency",
"value":"hotel_currency"
},
{
"name":"Argentine Peso",
"value":"ARS"
},
... and other currencies
],
"filters":{
"budget":[
{
"name":"US$0 – US$50",
"value":"pri=1"
},
{
"name":"US$50 – US$100",
"value":"pri=2"
},
... and other budget options
],
"propertyRating":[
{
"name":"1 star",
"value":"class=1"
},
{
"name":"2 stars",
"value":"class=2"
},
{
"name":"3 stars",
"value":"class=3"
},
... and other rating options
],
... and other filters
}
}
接下来,使用在一系列过滤器(["pri=2", "3 stars"]
),货币,设置位置,日期,客人数量和设置为商业目的之前使用:
ð注意:您可以同时将name
或value
用于过滤器和货币。
booking
.getHotels(["pri=2", "3 stars"], "Argentine Peso", undefined, "Miami", "22/05/2023", "27/05/2023", 3, 1, undefined, "business")
.then(console.log);
-
["pri=2", "3 stars"]
-我们选择一个预算过滤器,其价格限制为“ 50美元US $ 100”和具有“ 3星”限制的物业评级过滤器; -
"Argentine Peso"
-选定的货币; -
undefined
-未设置resultsLimit
参数。这意味着我们离开默认结果限制(booking
的35); -
"Miami"
-选定位置; -
"22/05/2023"
-检查日期; -
"27/05/2023"
-查看日期; -
3
-成人金额; -
1
-儿童金额; -
undefined
-没有设置rooms
参数。这意味着我们将默认需要的房间数量(13); -
"business"
-我们选择“旅行工作”过滤器;
输出:
[
{
"thumbnail":"https://cf.bstatic.com/xdata/images/hotel/square200/277583459.webp?k=d90d11e2d824655526e06df6a5ddc759b715e9a27cb6ed1d8351a1a3a4e67b03&o=&s=1",
"title":"Holiday Inn Express Doral Miami, an IHG Hotel",
"stars":3,
"preferredBadge":true,
"promotedBadge":false,
"location":"Doral",
"subwayAccess":false,
"distanceFromCenter":17.7,
"highlights":[
],
"rating":{
"score":9,
"scoreDescription":"Wonderful",
"reviews":1396
},
"link":"https://www.booking.com/hotel/us/holiday-inn-express-doral-miami.html?lang=en-us"
},
{
"thumbnail":"https://cf.bstatic.com/xdata/images/hotel/square200/379622649.webp?k=ed10fc85de5b55f776d6d5f2337bd823566039afd770a5f8a395d24e5308399f&o=&s=1",
"title":"Best Western Plus Windsor Inn",
"stars":3,
"preferredBadge":true,
"promotedBadge":false,
"location":"North Miami",
"subwayAccess":false,
"distanceFromCenter":13.3,
"highlights":[
],
"rating":{
"score":7.7,
"scoreDescription":"Good",
"reviews":644
},
"link":"https://www.booking.com/hotel/us/best-western-windsor-inn.html?lang=en-us"
},
... and other hotels
]
然后使用其中一个酒店链接获取酒店信息:
booking.getHotelInfo("https://www.booking.com/hotel/us/holiday-inn-express-doral-miami.html?lang=en-us").then((data) => {
console.dir(data, { depth: null });
});
输出:
{
"title":"Holiday Inn Express Doral Miami, an IHG Hotel",
"type":"Hotel",
"stars":3,
"preferredBadge":true,
"subwayAccess":false,
"sustainability":"",
"address":"1691 NW 107th Ave, Doral, FL 33172, United States of America",
"highlights":[
"Free WiFi",
"Free parking",
"Air conditioning",
"Private Bathroom",
"24-hour front desk",
"Key card access",
"Daily housekeeping",
"Non-smoking rooms",
"Safe",
"Baggage storage"
],
"description":"Located a 13-minute walk from Miami International Mall, Holiday Inn Express Doral Miami, an IHG Hotel offers 3-star accommodations in Doral and has a shared lounge. Featuring a fitness center, the 3-star hotel has air-conditioned rooms with free WiFi, each with a private bathroom. Guests can have a drink at the snack bar.\n""+""All rooms at the hotel come with a seating area, a flat-screen TV with satellite channels and a safety deposit box. At Holiday Inn Express Doral Miami, an IHG Hotel all rooms include bed linen and towels.\n""+""An American breakfast is available every morning at the accommodation.\n""+""Guests at Holiday Inn Express Doral Miami, an IHG Hotel will be able to enjoy activities in and around Doral, like cycling.\n""+""Free private parking and a business center are available, as well as a 24-hour front desk.\n""+""Dolphin Mall is a 17-minute walk from the hotel, while University of Miami is 17.7 km from the property. The nearest airport is Miami International Airport, 6 km from Holiday Inn Express Doral Miami, an IHG Hotel.",
"descriptionHighlight":"Couples in particular like the location – they rated it 9.2 for a two-person trip.",
"descriptionSummary":"Holiday Inn Express Doral Miami, an IHG Hotel has been welcoming Booking.com guests since Oct 19, 2020\n""+""\n""+""Hotel chain/brand:\n""+""Holiday Inn Express",
"facilities":[
"Free parking",
"Free WiFi",
"Fitness center",
"Facilities for disabled guests",
"Non-smoking rooms",
"Tea/Coffee Maker in All Rooms",
"Free parking",
"Free WiFi",
"Fitness center",
"Facilities for disabled guests",
"Non-smoking rooms",
"Tea/Coffee Maker in All Rooms"
],
"areaInfo":[
{
"What's nearby":[
{
"place":"Veteran's Park",
"distance":"1.8 km"
},
{
"place":"The Women's Park",
"distance":"2.3 km"
},
... and other nearby places
]
},
... and other area info
],
"link":"https://www.booking.com/hotel/us/holiday-inn-express-doral-miami.html?lang=en-us",
"photos":[
"https://cf.bstatic.com/xdata/images/hotel/max1024x768/277583459.jpg?k=da2b83dc681cb5c13878eb05d0bb838298092038e7d61b6df72a86631dcce9aa&o=&hp=1",
"https://cf.bstatic.com/xdata/images/hotel/max1024x768/294863203.jpg?k=8ad830f1aa24e541616b02550d32d9da8018a5889730b509db4ad801981b6588&o=&hp=1",
"https://cf.bstatic.com/xdata/images/hotel/max1024x768/277583540.jpg?k=ef279b7064a7b7c538f9e8fb437ef593fa4451f7186894af4ce9f4fd0602ecb0&o=&hp=1",
... and other photos
],
"reviewsInfo":{
"score":9,
"scoreDescription":"Rated wonderful",
"totalReviews":1419,
"categoriesRating":[
{
"Staff":9.2
},
{
"Facilities":9.2
},
{
"Cleanliness":9.3
},
{
"Comfort":9.3
},
{
"Value for money":8.8
},
{
"Location":9.2
},
{
"Free WiFi":8.8
}
],
"reviews":[
{
"name":"Barbara",
"avatar":"https://cf.bstatic.com/static/img/review/avatars/ava-b/8103dfb0481c4cedc201d849f5666a270512f538.png",
"country":"Bermuda",
"date":"April 3, 2023",
"reting":"10",
"review":[
{
"liked":"Breakfast was very good.\nThe food was hot\nCoffee was good"
},
{
"didNotLike":"Nothing"
}
],
"hotelResponse":"Hello, thank you for your feedback! We are glad you enjoyed your stay."
},
... and other reviews
]
}
}
Hotels.com选择的酒店信息结果。
首先,我们需要获得酒店链接:
hotelsCom.getHotels().then(console.log);
输出:
[
{
"title":"Hotel 10 Opera",
"isAd":true,
"location":"Paris",
"snippet":{
"title":"3* hotel located near the Opera",
"text":"In the heart of the 9th district: customized offers according to the length of stay, flexibility & reinforced sanitary measures."
},
"paymentOptions":[
"Fully refundable",
"Reserve now, pay later"
],
"highlightedAmenities":[
],
"price":{
"currency":"$",
"value":274,
"withTaxesAndCharges":305
},
"rating":{
"score":8.8,
"reviews":36
},
"link":"https://www.hotels.com/ho282954/hotel-10-opera-paris-france/"
},
... and other hotels
]
然后我们使用酒店链接并获得酒店信息结果:
hotelsCom.getHotelInfo("https://www.hotels.com/ho282954/hotel-10-opera-paris-france/").then((result) => console.dir(result, { depth: null }));
输出:
{
"title":"Hotel 10 Opera",
"stars":3,
"shortDescription":"City-center hotel within walking distance of Palais Garnier",
"address":"10, Rue du Helder, Paris, Paris, 75009",
"description":"Hotel 10 Opera offers a great location, putting you within a 15-minute walk of Palais Garnier and Louvre Museum. Also, Champs-Élysées and La Machine du Moulin Rouge are just a 5-minute drive away. Fellow travelers say great things about the local sightseeing and quiet guestrooms. The property is just a short walk to public transportation: Chaussee d'Antin - La Fayette Station is 3
minutes and Opéra Station is 3 minutes.",
"languages":"English, French, Portuguese, Spanish",
"roomOptions":[
"Room",
"Twin Room",
"Double Room Single Use",
"Family Room"
],
"areaInfo":[
{
"What's nearby":[
{
"place":"In Paris City Center"
},
{
"place":"Galeries Lafayette",
"distance":"3 min walk"
},
... and other nearby places
]
},
... and other aria info
],
"CleaningAndSafety":[
{
"Enhanced cleanliness measures":[
"Disinfectant is used to clean the property",
"High-touch surfaces are cleaned and disinfected",
"Sheets and towels are washed at 60°C/140°F or hotter"
]
},
... and other cleaning and safety options
],
"atAGlance":[
{
"Hotel size":[
"34 rooms",
"Arranged over 6 floors"
]
},
... and other at a glance options
],
"propertyAmenities":[
{
"Food and drink":[
"Buffet breakfast (surcharge) each morning 7 AM–10:30 AM",
"Coffee/tea in a common area",
"Room service (limited hours)"
]
},
... and other property amenities
],
"roomAmenities":[
{
"Be entertained":[
"Television",
"Satellite TV channels"
]
},
... and other room amenities
],
"specialFeatures":[],
"feesAndPolicies":[
{
"Mandatory fees":[
"A tax is imposed by the city: EUR 1.88 per person, per night. This tax does not apply to children under 18 years of age."
]
},
... and other fees and policies
],
"link":"https://www.hotels.com/ho282954/hotel-10-opera-paris-france/",
"photos":[
"https://images.trvl-media.com/lodging/2000000/1550000/1542800/1542774/b08e7322.jpg?impolicy=resizecrop&rw=1200&ra=fit",
"https://images.trvl-media.com/lodging/2000000/1550000/1542800/1542774/8975206c.jpg?impolicy=resizecrop&rw=1200&ra=fit",
... and other photo
],
"reviewsInfo":{
"score":8.8,
"scoreDescription":"Fabulous",
"totalReviews":36,
"categoriesRating":[
{
"Cleanliness":9.4
},
... and more category rating
],
"reviews":[
{
"date":"Mar 21, 2023",
"reting":8,
"reviewTitle":"Will stay here again!!",
"review":"The hotel is located around around the corner of the Opera House and a 5 minute walk to Galerie Lafayette. It is 15 minutes walk to the Louvre. The location is perfect. The hotel is
clean, safe and the staff is friendly. Free water, coffee and tea in reception. Two things to be aware of: 1. small, simple room and tiny bathroom (you get what you pay for) and 2. Across the street from hotel is a popular restaurant with people on street. The restaurant closes at midnight so noise is not a problem if you are in the front. I plan to stay there again given the price, location, and service.",
"hotelResponse":"Dear Karen,Thank you for your feedback, we are delighted to see that you enjoyed your stay! Please feel free to tell us what we could improve to deserve a 10!Looking forward to welcoming you again"
},
... and other reviews
]
}
}
高级示例
从所有站点找到最便宜的酒店,获取前10个酒店信息,并保存结果。
完整代码:
import { airbnb, booking, hotelsCom, saveToJSON } from "./index.js";
const getHotels = async (location, checkIn, checkOut) => {
const hotels = [
...(await airbnb.getHotels(undefined, "USD", 50, location, checkIn, checkOut)),
...(await booking.getHotels(undefined, "USD", 50, location, checkIn, checkOut)),
...(await hotelsCom.getHotels(undefined, undefined, undefined, "United States", undefined, 50, location, checkIn, checkOut)),
];
return hotels
.sort((a, b) => {
let aValue = a.price?.value;
let bValue = b.price?.value;
if (a.price?.taxesAndCharges || (a.price?.period && a.price?.period !== "night")) {
aValue = a.price?.value / 10;
}
if (b.price?.taxesAndCharges || (b.price?.period && b.price?.period !== "night")) {
bValue = b.price?.value / 10;
}
return aValue - bValue;
})
.slice(0, 10);
};
const getInfo = async (hotels) => {
const results = [];
for (const hotel of hotels) {
const { link, price } = hotel;
if (link.includes("airbnb.com")) {
results.push({ ...(await airbnb.getHotelInfo(link)), price });
} else if (link.includes("booking.com")) {
results.push({ ...(await booking.getHotelInfo(link)), price });
} else results.push({ ...(await hotelsCom.getHotelInfo(link)), price });
}
return results;
};
getHotels("Miami", "07/18/2023", "07/28/2023").then(getInfo).then(saveToJSON);
说明:
首先,我们从位于“迈阿密”中的每个网站获得酒店,从07/18/2023
到07/28/2023
:
getHotels("Miami", "07/18/2023", "07/28/2023");
在getHotels
功能中,我们从每个网站获得50家酒店,然后按价格上涨,并保持10个最便宜的地方:
const getHotels = async (location, checkIn, checkOut) => {
const hotels = [
...(await airbnb.getHotels(undefined, "USD", 50, location, checkIn, checkOut)),
...(await booking.getHotels(undefined, "USD", 50, location, checkIn, checkOut)),
...(await hotelsCom.getHotels(undefined, undefined, undefined, "United States", undefined, 50, location, checkIn, checkOut)),
];
return hotels
.sort((a, b) => {
let aValue = a.price?.value;
let bValue = b.price?.value;
if (a.price?.taxesAndCharges || (a.price?.period && a.price?.period !== "night")) {
aValue = a.price?.value / 10;
}
if (b.price?.taxesAndCharges || (b.price?.period && b.price?.period !== "night")) {
bValue = b.price?.value / 10;
}
return aValue - bValue;
})
.filter((el, i) => i < 10);
};
收到酒店并过滤后,我们致电then
功能,并将收到的酒店送入getInfo
功能:
.then(getInfo)
在getInfo
中,我们迭代所有酒店,接收每个酒店信息,将它们推入results
阵列并返回:
const getInfo = async (hotels) => {
const results = [];
for (const hotel of hotels) {
const { link, price } = hotel;
if (link.includes("airbnb.com")) {
results.push({ ...(await airbnb.getHotelInfo(link)), price });
} else if (link.includes("booking.com")) {
results.push({ ...(await booking.getHotelInfo(link)), price });
} else results.push({ ...(await hotelsCom.getHotelInfo(link)), price });
}
return results;
};
和最后一个,我们将then
功能称为saveToJSON
功能:
.then(saveToJSON)
结果是您的应用程序目录中保存的parsed_results.json
文件,带有完整说明的前10个最便宜的酒店。
链接
如果您希望将其他功能添加到此演示项目中,或者您想查看其他一些由Serpapi制定的项目,write me a message。
添加Feature Requestð«或Bugð