如何获取Skiddle网站节日页面的动态HTML及节日详情链接?
解决Skiddle节日页面动态内容抓取问题
问题说明
尝试获取https://www.skiddle.com/festivals/dates.html页面的HTML内容以提取节日详情链接,但页面内容由JavaScript动态加载,使用requests直接请求只能拿到空的骨架页面,尝试过session和未完善的undetected_chromedriver方案均未成功。
可行解决方案
方案1:抓取后台API(高效推荐)
Skiddle的节日数据通过异步API接口加载,直接请求接口可获取结构化JSON数据,无需渲染页面,效率更高:
- 打开浏览器开发者工具(F12),切换到「网络」标签,刷新页面后筛选「XHR/fetch」请求,找到类似
/api/v1/festivals?dates=...的接口(具体路径以实际请求为准) - 接口返回的JSON数据中,每个节日条目包含
url字段,拼接域名即可得到详情页完整链接
示例代码:
import requests import json headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', 'Referer': 'https://www.skiddle.com/festivals/dates.html' } # 替换为实际抓取到的API接口,参数可按需调整分页、日期范围等 api_url = 'https://www.skiddle.com/api/v1/festivals?dates=all&page=1&limit=24' response = requests.get(api_url, headers=headers) if response.status_code == 200: data = json.loads(response.text) # 提取所有节日详情链接 festival_links = [f"https://www.skiddle.com{item['url']}" for item in data['results']] for link in festival_links: print(link) else: print(f"请求失败,状态码:{response.status_code}")
方案2:完善无头浏览器渲染方案
若API接口存在反爬限制,可使用undetected_chromedriver模拟真实浏览器行为,确保页面完全加载后再提取内容:
- 启用无头模式减少资源占用
- 用显式等待替代固定
time.sleep(),确保目标元素加载完成 - 禁用自动化标识规避反爬检测
示例代码:
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import undetected_chromedriver as uc def get_festival_links(url): options = uc.ChromeOptions() options.add_argument('--headless=new') # 无头模式 options.add_argument('--disable-blink-features=AutomationControlled') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') # 如需代理,取消注释并替换为有效代理地址 # options.add_argument('--proxy-server=http://146.247.105.71:4827') driver = uc.Chrome(options=options) try: driver.get(url) # 显式等待节日列表元素加载,超时10秒 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, '.card-body a')) ) # 提取所有详情链接 links = driver.find_elements(By.CSS_SELECTOR, '.card-body a') festival_links = [link.get_attribute('href') for link in links if link.get_attribute('href')] for link in festival_links: print(link) finally: driver.quit() if __name__ == '__main__': get_festival_links('https://www.skiddle.com/festivals/dates.html')
注意事项
- 频繁请求可能触发反爬机制,建议添加合理的请求间隔
- API接口的分页、日期范围等参数可按需调整,实现批量抓取
- 使用代理时需确保代理有效且未被目标网站封禁,否则会导致请求失败
内容的提问来源于stack exchange,提问作者POPIF
相关产品推荐
相关产品推荐

