Python-绕过携程反爬:Selenium实战景点信息采集

📅 2026/7/16 12:01:04
Python-绕过携程反爬:Selenium实战景点信息采集
1. 为什么选择Selenium来爬取携程景点数据第一次尝试用Python爬取携程景点信息时我像大多数人一样首先想到用requests库。但很快发现携程的页面数据是通过JavaScript动态加载的直接发送HTTP请求只能拿到空壳HTML。更麻烦的是页面请求中有一个叫traceid的加密参数每次都会变化这意味着传统的抓包参数复用的方法完全失效。这时候你有两个选择要么硬着头皮去逆向分析JavaScript加密逻辑要么换个思路用浏览器自动化工具。作为一个主要用爬虫辅助数据分析的开发者我果断选择了后者。Selenium最大的优势就是能模拟真实用户操作浏览器完全绕过各种前端加密和动态加载的问题。实测下来用Selenium采集携程景点信息的成功率接近100%而代码复杂度比逆向JS低至少三个量级。不过Selenium也不是完美方案它的缺点很明显——速度慢、资源占用高。我的经验是对于中小规模的数据采集比如某个城市几百个景点Selenium完全够用但如果要爬全国所有景点可能需要考虑结合requests和Selenium的混合方案。2. 环境搭建与基础配置2.1 安装必要的工具链首先确保你的Python环境是3.6以上版本。然后通过pip安装以下核心依赖pip install selenium pandas lxml浏览器驱动是Selenium的关键组件。以Chrome为例需要下载与本地Chrome版本匹配的chromedriver。将下载的驱动文件放在项目目录下或者添加到系统PATH中。这里有个小技巧使用headless模式无界面模式可以大幅降低资源消耗from selenium.webdriver import Chrome from selenium.webdriver.chrome.options import Options options Options() options.add_argument(--headless) # 无头模式 options.add_argument(--disable-gpu) # 避免一些兼容性问题 driver Chrome(optionsoptions)2.2 处理携程的页面加载特点携程的景点列表页有个特点翻页时URL不会变化传统的通过URL参数控制翻页的方法行不通。这就需要我们模拟点击下一页按钮的操作。另外页面加载需要一定时间必须合理设置等待策略from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 显式等待元素加载 wait WebDriverWait(driver, 10) next_btn wait.until(EC.element_to_be_clickable( (By.CLASS_NAME, u_icon_enArrowforward))) next_btn.click()3. 核心爬取逻辑实现3.1 定位并提取列表页数据携程景点列表页的核心数据都包裹在class为right-content-list的div中。我们可以先获取这个容器的HTML源码然后用正则表达式提取景点URL和名称content driver.find_element_by_class_name(right-content-list).get_attribute(innerHTML) url_title_pairs re.findall(rhref(.*?) title(.*?), content) for url, title in url_title_pairs: full_url https: url # 补全URL print(f景点名称{title}, 详情页URL{full_url})3.2 自动翻页机制由于携程采用动态加载我们需要用while循环配合页面元素检测来实现自动翻页。这里有个关键点必须设置合理的终止条件否则可能陷入无限循环。我的做法是预设最大爬取页数max_page 5 # 最多爬取5页 current_page 1 while current_page max_page: # 提取当前页数据... try: next_btn driver.find_element_by_class_name(u_icon_enArrowforward) next_btn.click() time.sleep(2) # 等待新页面加载 current_page 1 except: print(已到达最后一页) break4. 详情页数据提取技巧4.1 处理动态变化的详情模块景点详情页最棘手的部分是景点介绍、开放时间这些模块——它们数量不固定但HTML结构相似。我的解决方案是用XPath提取所有标题和内容然后通过Python的zip函数建立映射from lxml import etree html driver.page_source tree etree.HTML(html) titles tree.xpath(//div[classdetailModule normalModule]//div[classmoduleTitle]/text()) contents tree.xpath(//div[classdetailModule normalModule]//div[classmoduleContent]//text()) # 清理空白字符 titles [t.strip() for t in titles if t.strip()] contents [c.strip() for c in contents if c.strip()] # 转为字典 info_dict dict(zip(titles, contents))4.2 门票价格的特殊处理门票数据往往存在三种特殊情况价格为空、多价格并存、价格元素位置变化。这里需要多层异常处理prices [] for price_element in driver.find_elements_by_xpath(//*[contains(class, price)]): try: price price_element.text.replace(¥, ).strip() if price and price.isdigit(): prices.append(int(price)) except: continue if not prices: print(未找到价格信息) else: print(f参考价格区间{min(prices)}-{max(prices)}元)5. 反反爬策略实战5.1 模拟人类操作模式携程的反爬系统会检测异常操作。我们可以通过随机延迟和动作链来模拟人类行为from selenium.webdriver.common.action_chains import ActionChains import random element driver.find_element_by_class_name(some-class) ActionChains(driver).move_to_element(element).pause( random.uniform(0.5, 2)).click().perform()5.2 Cookie管理技巧登录状态可以大幅降低被反爬的概率。建议先手动登录然后导出cookie供爬虫使用# 获取当前所有cookie cookies driver.get_cookies() # 将cookie转换为requests可用的格式 session requests.Session() for cookie in cookies: session.cookies.set(cookie[name], cookie[value])6. 数据存储与后续处理6.1 结构化存储方案建议使用Pandas将数据转为DataFrame后再存储方便后续分析import pandas as pd data { name: [景点A, 景点B], price: [100, 150], rating: [4.5, 4.2] } df pd.DataFrame(data) # 保存为CSV df.to_csv(spots.csv, indexFalse, encodingutf-8-sig) # 保存为Excel df.to_excel(spots.xlsx, indexFalse)6.2 数据清洗的常见问题实际采集的数据往往需要清洗处理缺失值df.fillna(N/A)统一价格单位df[price] df[price].str.replace(¥, )去除重复项df.drop_duplicates(inplaceTrue)7. 项目优化与扩展7.1 性能优化技巧当需要爬取大量数据时可以考虑使用Selenium Grid分布式爬取将浏览器实例复用避免频繁启动关闭实现断点续爬功能# 断点续爬示例 try: with open(progress.txt, r) as f: last_page int(f.read()) except: last_page 17.2 扩展其他数据维度除了基础信息还可以采集用户评论注意频率控制季节性价格波动周边酒店关联数据这套方法同样适用于携程的酒店、机票等板块只需调整XPath和解析逻辑即可。最关键的是始终保持对目标网站的观察因为旅游网站的页面结构可能随时调整。当发现爬虫失效时第一时间检查元素定位是否仍然有效而不是盲目修改代码。