pyspider框架之Tripadvisor酒店数据爬取

article/2025/9/26 14:12:14
需求

网站入口:www.tripadvisor.com
这里写图片描述
网页下端,遍历点开进入所有城市链接:
这里写图片描述
点击后进入该城市的所有hotel
这里写图片描述

代码
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2018-09-06 11:16:59
# Project: trip_hotelfrom pyspider.libs.base_handler import *
import datetime
import re
import json
import copyfrom pymongo import MongoClient# 连接线下数据库
DB_IP = ''
DB_PORT = #DB_IP = '127.0.0.1'
#DB_PORT = 27017client = MongoClient(host=DB_IP, port=DB_PORT)# admin 数据库有帐号,连接-认证-切换
db_auth = client.admin
db_auth.authenticate("", "")DB_NAME = 'research'
db = client[DB_NAME]def get_today():return datetime.datetime.strptime(datetime.datetime.now().strftime('%Y-%m-%d'), '%Y-%m-%d')class Handler(BaseHandler):crawl_config = {'headers': {'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36','cookie':'SetCurrency=USD'},'proxy': 'http://10.15.100.94:6666','retries': 5}url = 'https://www.tripadvisor.com/'@every(minutes=24 * 60)def on_start(self):self.crawl(self.url, callback=self.index_page)@config(age=60)def index_page(self, response):page = response.etreecity_list = page.xpath("//div[@class='customSelection']/div[@class='boxhp collapsibleLists']/div[@class='section']/div[@class='ui_columns' or @class='ui_columns no-collapse']/ul[@class='lst ui_column is-4']/li[@class='item']")print(len(city_list))base_url = 'https://www.tripadvisor.com'for each in city_list:city_name = each.xpath("./a/text()")[0]city_link = base_url + each.xpath("./a/@href")[0]print(city_name, '---', city_link)save = {"city": city_name}self.crawl(city_link, callback=self.parse_city, save=save)@config(age=60)def parse_city(self, response):page = response.etreebase_url = 'https://www.tripadvisor.com'## 国家country = page.xpath("//div[@id='taplc_trip_planner_breadcrumbs_0']/ul[@class='breadcrumbs']/li[1]/a/span/text()")[0]print(country)## 第一需求表## 翻页#page_list = [response.url]#page_list.extend([base_url+i for i in page.xpath("//div[@class='pageNumbers']/a/@href")])#print(len(page_list))save = {"country": country, "city": response.save["city"]}#for each in page_list:#    self.crawl(each, callback=self.parse_page, save=save)tail_url = page.xpath("//div[@class='pageNumbers']/a[last()]/@href")[0]total_num = re.findall('oa(\d+)-',tail_url)[0]page_url = base_url + tail_url.replace(total_num,'{}')print(page_url)total_page = int(total_num)//30for i in range(total_page+1):if i == 0:self.crawl(response.url, callback=self.parse_page, save=save)else:self.crawl(page_url.format(30*i), callback=self.parse_page, save=save)## 第三个需求表new_url = response.url.replace('Hotels','Tourism').replace('Hotels', 'Vacations')print(new_url)self.crawl(new_url, callback=self.parse_detail, save=save)def parse_detail(self, response):page = response.etreehotel_num = page.xpath("//div[@class='navLinks']/ul/li[@class='hotels twoLines']//span[@class='typeQty']/text()")hotel_num = hotel_num[0] if hotel_num else ''print(hotel_num)hotel_reviews = page.xpath("//div[@class='navLinks']/ul/li[@class='hotels twoLines']//span[@class='contentCount']/text()")hotel_reviews = hotel_reviews[0] if hotel_reviews else ''print(hotel_reviews)rentals_num = page.xpath("//div[@class='navLinks']/ul/li[@class='vacationRentals twoLines']//span[@class='typeQty']/text()")rentals_num = rentals_num[0] if rentals_num else ''print(rentals_num)        rentals_reviews = page.xpath("//div[@class='navLinks']/ul/li[@class='vacationRentals twoLines']//span[@class='contentCount']/text()")rentals_reviews = rentals_reviews[0] if rentals_reviews else ''print(rentals_reviews)thingstodo_num = page.xpath("//div[@class='navLinks']/ul/li[@class='attractions twoLines']//span[@class='typeQty']/text()")thingstodo_num = thingstodo_num[0] if thingstodo_num else ''print(thingstodo_num)thingstodo_reviews = page.xpath("//div[@class='navLinks']/ul/li[@class='attractions twoLines']//span[@class='contentCount']/text()")thingstodo_reviews = thingstodo_reviews[0] if thingstodo_reviews else ''print(thingstodo_reviews)restaurant_num = page.xpath("//div[@class='navLinks']/ul/li[@class='restaurants twoLines']//span[@class='typeQty']/text()")restaurant_num = restaurant_num[0] if restaurant_num else ''print(restaurant_num)restaurant_reviews = page.xpath("//div[@class='navLinks']/ul/li[@class='restaurants twoLines']//span[@class='contentCount']/text()")restaurant_reviews = restaurant_reviews[0] if restaurant_reviews else ''print(restaurant_reviews)  forum_post = page.xpath("//div[@class='navLinks']/ul/li[@class='forum twoLines']//span[@class='contentCount']/text()")forum_post = forum_post[0] if forum_post else ''print(forum_post)  result = {"country": response.save["country"],"city": response.save["city"],"hotel_num": hotel_num,"hotel_reviews": hotel_reviews,"rentals_num": rentals_num,"rentals_reviews": rentals_reviews,"thingstodo_num": thingstodo_num,"thingstodo_reviews": thingstodo_reviews,"restaurant_num": restaurant_num,"restaurant_reviews": restaurant_reviews,"forum_post": forum_post,"date": get_today(),"collection": 'trip_total_daily_data'}yield result@config(age=60)def parse_page(self, response):page = response.etree## 酒店列表#content_list = page.xpath("//div[@id='taplc_hsx_hotel_list_lite_dusty_hotels_combined_sponsored_0']/div[@class='prw_rup prw_meta_hsx_responsive_listing ui_section listItem  ']")content_list = page.xpath("//div[@id='taplc_hsx_hotel_list_lite_dusty_hotels_combined_sponsored_0']/div/div[@class!='prw_rup prw_common_ad_resp ui_section is-ad  ']")print(len(content_list))for each in content_list:price_1 = each.xpath(".//div[@class='priceBlock ui_column is-12-tablet']//div[@class='price autoResize']/text()")price_1 = (price_1[0] if price_1 else '')price_origin = each.xpath(".//div[@class='priceBlock ui_column is-12-tablet']//div[@class='xthrough autoResize']/div/text()")if price_origin:price_origin = price_origin[0]else:price_origin = ''hotel_name = each.xpath(".//div[@data-prwidget-name='meta_hsx_listing_name']//a/text()")[0]hotel_id = each.xpath(".//div[@data-prwidget-name='meta_hsx_listing_name']//a/@id")[0]print(hotel_name, hotel_id)print(price_1, price_origin)reviews = each.xpath(".//a[@class='review_count']/text()")[0]print(reviews)web_1 = each.xpath(".//div[@class='priceBlock ui_column is-12-tablet']//div[@class='provider autoResize']/text()")[0]print(web_1)web_2 = each.xpath(".//div[@class='text-links is-shown-at-tablet has_commerce']/div[1]/div[@class='vendor']/span/text()")web_2 = (web_2[0] if web_2 else '')price_2 = each.xpath(".//div[@class='text-links is-shown-at-tablet has_commerce']/div[1]/div[@class='price autoResize']/text()")price_2 = (price_2[0] if price_2 else '')print(web_2, price_2)web_3 = each.xpath(".//div[@class='text-links is-shown-at-tablet has_commerce']/div[2]/div[@class='vendor']/span/text()")web_3 = (web_3[0] if web_3 else '')price_3 = each.xpath(".//div[@class='text-links is-shown-at-tablet has_commerce']/div[2]/div[@class='price autoResize']/text()")price_3 = (price_3[0] if price_3 else '')print(web_3, price_3)web_4 = each.xpath(".//div[@class='text-links is-shown-at-tablet has_commerce']/div[3]/div[@class='vendor']/span/text()")web_4 = (web_4[0] if web_4 else '')price_4 = each.xpath(".//div[@class='text-links is-shown-at-tablet has_commerce']/div[3]/div[@class='price autoResize']/text()")price_4 = (price_4[0] if price_4 else '')print(web_4, price_4)result = {"date": get_today(),"country": response.save["country"],"city": response.save["city"],"hotel_name": hotel_name,"hotel_id": hotel_id,"reviews": reviews,"price_origin": price_origin,"1_web": web_1,"1_price": price_1,"2_web": web_2,"2_price": price_2,"3_web": web_3,"3_price": price_3,"4_web": web_4,"4_price": price_4,"update_time": datetime.datetime.now(),"collection": "trip_hotel_daily_data"}yield resultdef on_result(self, result):super(Handler, self).on_result(result)if not result:returncol_name = result.pop("collection")col = db[col_name]if col_name == 'trip_hotel_daily_data':            update_key = {'date': result["date"],'hotel_id': result["hotel_id"]}elif col_name == 'trip_total_daily_data':update_key = {'date': result["date"],'city': result["city"]}col.update(update_key, {'$set': result}, upsert=True)            

http://chatgpt.dhexx.cn/article/rd5IUK2u.shtml

相关文章

爬取携程和蚂蜂窝的景点评论数据\携程评论数据爬取\旅游网站数据爬取

本人长期出售超大量微博数据、旅游网站评论数据,并提供各种指定数据爬取服务,Message to YuboonaZhang@Yahoo.com。同时欢迎加入社交媒体数据交流群:99918768 前言 为了获取多源数据需要到各个网站获取一些景点的评论信息和图片,首先选到了携程和蚂蜂窝这两个网站,将一些…

Python爬虫实战--TripAdvisor爬虫

目标站点分析 目标URL:https://www.tripadvisor.cn/Attractions-g60763-Activities-New_York_City_New_York.html#FILTERED_LIST 明确内容: 在图中,我们明确爬去的内容为:title,comment, cate(即绿色框中的…

如何用Python从TripAdvisor抓取数十万条酒店评论

我从TripAdvisor抓取一些酒店评论,然后发现了一种从它们那里刮掉数十万条酒店评论的好方法。 让我们假设,例如,我们要从大加那利岛刮掉酒店评论。如果转到TripAdvisor,我们将看到URL为: https://www.tripadvisor.com…

美通企业日报 | 猫途鹰联手携程打造中国顶级旅行平台;强生战略合作阿里旗下Lazada...

今日看点 TripAdvisor与携程集团联手打造面向中国出境旅行者的顶级旅行平台。全球领先的旅游平台TripAdvisor(猫途鹰)宣布其中国子公司已与携程集团达成战略合作,以打造中国顶级的旅行计划和预订网站,为渴望探索世界的中国旅行者提…

Python爬取TripAdvisor

直接上代码: #爬取tripadvisor纽约市酒店超值排名#引入requests 获取html文件,才能从html获取信息 import requests #利用BeautifulSoup解析文件,获取想要的到的数据 from bs4 import BeautifulSoup #这段代码只用在获取等待,避免…

猫途鹰公布2023年全球十大最佳旅行体验和十大顶级景点 | 美通社头条

美通社消息,旅游指南平台猫途鹰(Tripadvisor)公布2023年旅行者之选:最佳“必做之事”。 随着夏季旅游的全面展开,这些是猫途鹰评论家们最喜欢的来自世界各地的活动,为希望创造难忘时刻的旅行者提供一份明确的非凡体验清单&#xf…

猫途鹰公布2019年“旅行者之选”全球最佳海滩榜单

全球旅游规划和预订平台猫途鹰(TripAdvisor)公布2019年“旅行者之选”最佳海滩榜单。获奖海滩是基于过去12个月内全球上亿旅行者的评分和点评的数量及质量综合计算得出,巴西费尔南多迪诺罗尼亚群岛(Fernando de Noronha)的桑乔湾海滩&#xf…

【Python】代码:获取猫途鹰的London酒店信息:基于Scrapy框架和requests库

本文以代码分析的形式记录:利用Scrapy框架和requests库爬取tripadvisor(猫途鹰)多个城市的酒店信息,数据量300w条(1.09G),运行时间约7h。多个城市与单个城市的操作类似,为避免代码过于冗长,本文仅以爬取London酒店的评…

利用 pyspider 框架抓取猫途鹰酒店信息

利用框架 pyspider 能实现快速抓取网页信息,而且代码简洁,抓取速度也不错。 环境:macOS;Python 版本:Python3。 1.首先,安装 pyspider 框架,使用pip3一键安装: pip3 pyspider 2.终端…

可怕的pyspider猫途鹰

1.启动pyspider 2.新建一个项目 3.代码 4. 注意事项:网址什么的都变了 5.存储到MongoDB, 注意这个地方我错了三次 6.在tableau可视化才发现错误的1,2 之后就能可视化了,本次实验是个半成品。后期会补充。 #!/usr/bin/env python # -*- enco…

爬虫-猫途鹰

from bs4 import BeautifulSoup import requests url https://www.tripadvisor.cn/ wb_data requests.get(url) soup BeautifulSoup(wb_data.text,lxml) for i in soup.select(li):if len(i.select(.ranking))>0:sorti.select(.ranking)[0].text #排名countryi.select(.c…

JS DOM 编程复习笔记--父元素、子元素和兄弟元素(三)

今天我们来复习DOM中的获取父元素、子元素和兄弟元素的API,它们主要有parentNode、firstChild、firstElementChild、lastChild、lastElementChild、childNodes、children、nextElementSibling、nextSibling、previousElementSibling、previousSibling等。 目录 获取…

jquery 在兄弟节点前、或兄弟节点后添加最新元素

使用 jquery 封装好的方法操作 dom&#xff0c;非常方便 1、在兄弟节点前添加最新元素 使用 before() 方法 演示代码如下 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><script src"js/jquery-…

CSS第一章:4.元素关系(兄弟、祖后代关系);关系选择器

总览 1.元素关系 2.关系选择器 一、元素关系 1.元素关系1&#xff1a;父子 父元素&#xff1a;直接包含子元素的元素叫做父元素 子元素&#xff1a;直接被父元素包含的元素叫做子元素 2.元素关系2&#xff1a;祖先后代 祖先元素&#xff1a;直接或间接包含后代元素的元素…

选择兄弟元素中的第几个元素

:nth-child(anb) 这个CSS伪类首先找到所有当前元素的兄弟元素&#xff0c;然后按照位置先后顺序从1开始排序&#xff0c;选择的结果为CSS伪类:nth-child括号中表达式&#xff08;anb&#xff09;匹配到的元素集合&#xff08;n0&#xff0c;1&#xff0c;2&#xff0c;3...&am…

兄弟元素选择器

兄弟元素选择器 语法1&#xff1a;前一个元素 后一个元素作用&#xff1a;选中一个元素后紧挨着的指定的兄弟元素。语法2&#xff1a;前一个元素 ~ 后边一类元素作用&#xff1a;选中后边的所有兄弟元素 举例1&#xff1a; <!DOCTYPE html> <html lang"en&qu…

Thinking -- CSS从根解决选择前一个兄弟元素

Thinking系列&#xff0c;旨在利用10分钟的时间传达一种可落地的编程思想。 开发中遇到这样一个诉求&#xff1a;特定class的元素单独占一行&#xff0c;现需要针对其前一个兄弟元素增加相应标识&#xff0c;以使其占据所在行的剩余所有空间。 换句话&#xff1a;就是如何选中…

JS 兄弟元素和兄弟节点

获取兄弟节点和兄弟元素 例子&#xff1a; //body内容<ul id"ul">wwwwww<!-- 我是注释 --><li>我是li标签1</li><li id"li2">我是li标签2</li><li>我是li标签3</li><li>我是li标签4</li><…

css-知识点(学习笔记)

一、鼠标悬停样式 hover伪类基础用法 在前端学习的初期&#xff0c;想必大家用的很多的属性之一就有hover吧,hover伪类元素使用的三种情况 1、 hover用于父子元素 父子元素直接在父元素的id或者class或者标签名后紧接着:hover 然后空格子元素的名字就可以了。 2、 hover用于…

RPC原理及其调用过程

RPC原理及其调用过程 远程过程调用&#xff0c;简称为RPC&#xff0c;是一个计算机通信协议&#xff0c;它允许运行于一台计算机的程序调用另一台计算机的子程序&#xff0c;而无需额外地为这个交互作用编程。 RPC与传统的HTTP对比 优点&#xff1a; 1. 传输效率高(二进制传输…