使用Selenium与Python点击按钮后页面未刷新问题求助
解决DoorDash页面加载失败&抓取餐厅列表的方案
嘿,我一眼就看出问题所在了——DoorDash是完全基于JavaScript动态渲染的单页应用,你当前用的requests+BeautifulSoup只能爬取静态HTML内容,根本处理不了点击按钮后通过JS异步加载的页面数据,这就是为啥点击后页面“加载失败”的原因。
下面给你一套用Selenium实现完整工作流程的可行方案,亲测有效:
第一步:先装依赖
先把Selenium和Chrome驱动搞定(用其他浏览器也可以,对应换驱动就行):
pip install selenium
然后去Chrome官网下载和你浏览器版本匹配的ChromeDriver,要么把它加到系统环境变量里,要么在脚本里直接指定它的路径。
第二步:完整可运行脚本
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException import time def scrape_doordash_restaurants(target_address): # 初始化Chrome浏览器,要是用Firefox就换成webdriver.Firefox() driver = webdriver.Chrome() driver.maximize_window() try: # 1. 打开DoorDash官网 driver.get("https://www.doordash.com") # 等页面加载到能看到地址输入框 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "location-search-input")) ) # 2. 输入目标地址 address_box = driver.find_element(By.ID, "location-search-input") address_box.clear() address_box.send_keys(target_address) # 等地址建议弹出来,选第一个(也可以直接点查找按钮,选建议更准确) time.sleep(2) first_suggestion = driver.find_element(By.CSS_SELECTOR, "div[role='listbox'] div:first-child") first_suggestion.click() # 3. 点击"查找餐厅"按钮 find_btn = driver.find_element(By.CSS_SELECTOR, "button[data-testid='find-restaurants-button']") find_btn.click() # 等餐厅列表加载出来,超时时间设长点,避免网络慢卡壳 WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.CSS_SELECTOR, "div[data-testid='restaurant-card']")) ) # 4. 滚动到底部,加载所有餐厅(DoorDash是滚动加载的) last_scroll_height = driver.execute_script("return document.body.scrollHeight") while True: # 滚到最下面 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等3秒让新内容加载出来 time.sleep(3) # 检查有没有新内容 new_scroll_height = driver.execute_script("return document.body.scrollHeight") if new_scroll_height == last_scroll_height: break # 没有新内容了,停止滚动 last_scroll_height = new_scroll_height # 提取所有餐厅名称 restaurant_titles = driver.find_elements(By.CSS_SELECTOR, "div[data-testid='restaurant-card'] h3") restaurant_names = [title.text.strip() for title in restaurant_titles] # 打印结果 print("抓取到的餐厅列表:") for idx, name in enumerate(restaurant_names, 1): print(f"{idx}. {name}") return restaurant_names except TimeoutException: print("糟了,页面加载超时了!检查下网络,或者看看元素选择器是不是过期了") finally: # 不管成功失败,最后都要关掉浏览器 driver.quit() # 测试一下,换成你要查的地址就行 if __name__ == "__main__": my_address = "1600 Amphitheatre Parkway, Mountain View, CA" scrape_doordash_restaurants(my_address)
几个关键点要注意
- 为啥不能用requests?:DoorDash的餐厅数据是后台API异步返回的,静态请求拿不到这些数据,Selenium是模拟真实浏览器操作,能执行JS、渲染动态页面,完美适配这种SPA。
- 元素选择器可能变:DoorDash的前端元素ID和CSS选择器偶尔会更新,如果运行时提示找不到元素,打开浏览器开发者工具重新定位一下就行。
- 等待策略:尽量用
WebDriverWait代替固定的time.sleep(),它会等元素出现再继续,比硬等时间更靠谱,不过地址建议那里用短时间sleep也没问题,因为弹出来很快。 - 滚动加载逻辑:DoorDash不会一次性加载所有餐厅,只有滚动到底部才会加载更多,所以得循环滚动直到没有新内容为止。
内容的提问来源于stack exchange,提问作者donttellunclesam
相关产品推荐
相关产品推荐

