随着“五一“小长假的临近,各地旅游产品进入“冲刺”阶段,多地酒店房价也随之“水涨船高”。
很多网友在网上吐槽,搜索发现全国各地旅游城市热门景点附近的酒店在“五一”假期前3天的价格均较平日高出2-3倍,甚至还有酒店价格上涨5倍,令人直呼“酒店刺客”。
根据一些业内人士的发言来看, 今年五一假期全国酒店价格普遍上涨,可以从供求两方面来解释:首先,在供给端,经历了三年疫情,国内酒店供给大幅减少。其次,今年年初以来国内商务旅行及旅游度假需求出现了超预期的复苏。与需求端的快速反弹相比,供给端的修复则需要相对较长的周期,而“五一”假期出游需求集中释放更加剧了当前供给不足的问题,尤其是热门旅游目的地住宿设施供给严重不足,价格上涨是必然的。
但是价格的涨幅太大,也让旅客觉得自己被宰,难”五一“这些酒店的涨幅相比疫情之前是多还是少呢?这里我们可以通过python爬取历史数据来对比下。这里我们就以携程网上的酒店价格为数据来源。这里我发现新手在这里我发现新手在爬取某个网站的时候有个误区,就是他们觉得爬虫都是 “通用” 的,一个网站的爬虫拿过来,网址改一下,再随便撺吧撺吧就可以爬另一个网站了。
实际上,每一个网站的爬取都是需要单独进行分析的,你需要找到目标数据是在网页上的什么位置,是通过静态还是动态的方式加载进去的,网站是否有难搞的反爬虫措施,等等,从而来制定自己爬虫的爬取策略。像携程爬取的数据多了就会触碰封ip的反爬机制,这种情况下我们只有通过添加优质动态ip池来解决,这里我们就可以使用python通过Keep-Alive保持IP不变,向多个页面发出请求,通过多线程实现并发控制然后获取数据,ip的选择的由亿牛云提供的爬虫加强版ip池,实现过程如下:
代码语言:javascript复制#! -*- encoding:utf-8 -*-
import requests
import random
import requests.adapters
import threading # 导入threading模块
import time # 导入time模块
# 要访问的目标页面
targetUrlList = [
"https://https://www.ctrip.com/",
"https://httpbin.org/headers",
"https://httpbin.org/user-agent",
]
# 代理服务器(产品官网 www.16yun.cn)
proxyHost = "t.16yun.cn"
proxyPort = "31111"
# 代理验证信息
proxyUser = "SFEDEWE"
proxyPass = "785878"
proxyMeta = f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}"
# 设置 http和https访问都是用HTTP代理
proxies = {
"http": proxyMeta,
"https": proxyMeta,
}
# 定义一个全局变量,用于记录上一次请求的时间
last_request_time = 0
# 定义一个全局变量,用于创建一个线程锁
lock = threading.Lock()
# 定义一个函数,用于访问一个目标网址
def visit_url(url, i):
global last_request_time # 声明全局变量
with requests.session() as s: # 使用with语句管理会话
with lock: # 使用线程锁
# 获取当前时间
current_time = time.time()
# 计算距离上一次请求的时间差
delta_time = current_time - last_request_time
# 如果时间差小于200毫秒,就等待一段时间
if delta_time < 0.2:
time.sleep(0.2 - delta_time)
# 更新上一次请求的时间
last_request_time = time.time()
# 发送请求
r = s.get(url, proxies=proxies)
print(f"第{i 1}个网址,结果如下:") # 使用f-string格式化输出
print(r.text)
# 创建一个空的线程列表
threads = []
for i, url in enumerate(targetUrlList): # 使用enumerate函数遍历列表
# 创建一个线程,传入目标网址和索引
t = threading.Thread(target=visit_url, args=(url, i))
# 将线程添加到线程列表
threads.append(t)
# 启动线程
t.start()
# 等待所有线程结束
for t in threads:
t.join()