如何使用Selenium正确滚动动态加载网页实现稳定的酒店链接抓取
酒店搜索页面链接稳定抓取方案
问题描述
需要抓取目标页面 fr.hotels.com酒店搜索结果页 中的酒店链接,现有代码采用固定次数滚动的方式,存在抓取数量不稳定、无法自动停止的问题,要求实现可控、稳定的抓取结果,不需要获取全部链接也可。
现有代码如下:
import pandas as pd import numpy as np from selenium import webdriver import time PATH = "driver\chromedriver.exe" options = webdriver.ChromeOptions() options.add_argument("--disable-gpu") options.add_argument("--window-size=1200,900") options.add_argument('enable-logging') driver = webdriver.Chrome(options=options, executable_path=PATH) driver.get('https://fr.hotels.com/search.do?destination-id=10398359&q-check-in=2021-06-24&q-check-out=2021-06-25&q-rooms=1&q-room-0-adults=2&q-room-0-children=0&sort-order=BEST_SELLER') cookie = driver.find_element_by_xpath('//button[@class="uolsaJ"]') try: cookie.click() except: pass for i in range(30): driver.execute_script("window.scrollBy(0, 1000)") time.sleep(5) time.sleep(5) my_elems = driver.find_elements_by_xpath('//a[@class="_61P-R0"]') links = [my_elem.get_attribute("href") for my_elem in my_elems] X = np.array(links) print(X.shape) #driver.close()
优化方案
核心优化逻辑
- 替换固定滚动次数逻辑,通过滚动前后页面高度对比判断是否已到页面底部,适配不同网络环境下的加载速度
- 增加可配置的目标抓取数量阈值,达到指定数量就提前停止,实现结果可控
- 优化元素等待逻辑,避免固定sleep时长导致的元素未加载漏抓问题
优化后代码
import numpy as np from selenium import webdriver import time from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC PATH = "driver\chromedriver.exe" # 可配置的目标抓取数量,达到该值就停止滚动,不需要固定数量可设为9999等大数 TARGET_LINK_COUNT = 50 options = webdriver.ChromeOptions() options.add_argument("--disable-gpu") options.add_argument("--window-size=1200,900") options.add_argument('enable-logging') driver = webdriver.Chrome(options=options, executable_path=PATH) driver.get('https://fr.hotels.com/search.do?destination-id=10398359&q-check-in=2021-06-24&q-check-out=2021-06-25&q-rooms=1&q-room-0-adults=2&q-room-0-children=0&sort-order=BEST_SELLER') # 处理cookie弹窗 try: cookie_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, '//button[@class="uolsaJ"]')) ) cookie_btn.click() except: pass # 滚动逻辑 last_height = driver.execute_script("return document.body.scrollHeight") while True: # 滚动到当前页面底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等待内容加载 time.sleep(3) # 统计当前已加载的链接数量 current_elems = driver.find_elements(By.XPATH, '//a[@class="_61P-R0"]') current_count = len(current_elems) # 达到目标数量直接停止 if current_count >= TARGET_LINK_COUNT: break # 判断是否已经滚动到底部 new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height # 提取链接,截取到目标数量即可 links = [elem.get_attribute("href") for elem in current_elems[:TARGET_LINK_COUNT]] X = np.array(links) print(f"实际抓取到链接数量:{X.shape[0]}") driver.quit()
注意事项
- 可根据自身需求调整
TARGET_LINK_COUNT的值,固定每次抓取的数量,实现结果可控 - 如果需要抓取全部链接,把
TARGET_LINK_COUNT设置为远大于页面实际酒店数量的值即可 - 页面类名如果发生更新(比如
_61P-R0),对应修改XPath中的类名即可
内容的提问来源于stack exchange,提问作者RandallCloud
相关产品推荐
相关产品推荐

