如何使用Python爬取JS执行重定向后的动态网页数据
实现方案
这个需求完全可以通过Python + Selenium落地,你碰到的结果页无法直接访问的问题,本质是网站做了会话态校验:计算结果和表单提交时生成的临时会话Cookie、上下文状态绑定,脱离提交会话单独访问URL自然会被重定向回表单页,不需要逆向JS计算逻辑,顺着Selenium的会话上下文做页面等待就能解决。
核心思路
全程复用同一个Selenium浏览器实例完成全流程操作:从打开表单页、填写参数、点击计算按钮,到等待跳转、提取数据、存储文件都在同一个浏览器上下文中执行,会话Cookie会被自动携带,网站会判定请求是正常表单提交链路过来的,不会触发重定向拦截。
注意:点击按钮后不要立刻抓取页面内容,必须显式等待页面跳转完成、结果DOM渲染完毕再提取,这是新手最容易踩的坑——点完按钮马上取源码,拿到的只会是跳转前的表单页内容。
分步实现
安装依赖
直接用pip安装所需包,webdriver-manager会自动匹配对应版本的浏览器驱动,不用手动下载配置:pip install selenium pandas openpyxl webdriver-manager可直接复用的代码框架
核心用Selenium自带的显式等待判断URL变化和结果元素加载,比固定sleep稳定很多:from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import pandas as pd # 初始化浏览器实例,全流程不要新建其他实例 driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) # 设置最长20秒等待超时,覆盖网络慢、JS计算耗时的场景 wait = WebDriverWait(driver, 20) # 打开初始表单页面 driver.get("https://www.budgetthuis.nl/energie/") # 此处填写你已经实现的表单填充逻辑:选择地址、填写用电量/用气量、选择合同类型等 # 表单填完后定位「bereken aanbod」按钮点击即可 # calc_btn = driver.find_element(By.XPATH, "//button[normalize-space(text())='bereken aanbod']") # calc_btn.click() # 关键步骤:等待跳转和结果加载 # 先等待URL脱离初始表单路径 wait.until(EC.url_changes("https://www.budgetthuis.nl/energie/")) # 再等待结果页的标志性元素加载完成,把CSS选择器替换成你要抓的结果区块的实际选择器即可 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".offer-block, .total-price-wrapper"))) # 此时结果页已经完全渲染,直接提取数据即可 # 拿全页纯文本 page_text = driver.find_element(By.TAG_NAME, "body").text # 按需提取结构化字段,比如年费用、合同期限、固定费率等 # result = { # "annual_total_cost": driver.find_element(By.CSS_SELECTOR, ".total-annual-price").text, # "contract_term": driver.find_element(By.CSS_SELECTOR, ".contract-duration").text, # "capture_time": pd.Timestamp.now().isoformat() # } # 存储文件 # 存纯文本 with open("energie_offer_result.txt", "w", encoding="utf-8") as f: f.write(page_text) # 存Excel # pd.DataFrame([result]).to_excel("energie_offer_result.xlsx", index=False) # 操作完成关闭浏览器 driver.quit()
踩坑提醒
- 不要用
time.sleep(固定秒数)等待页面,网络波动时固定等待时长不足会导致抓取失败,用上面的显式等待逻辑,元素加载完成会立刻执行后续步骤,稳定性和效率都更高。 - 如果点击计算按钮后是新标签页打开结果,在等待元素前加一行
driver.switch_to.window(driver.window_handles[-1])切换到最新打开的标签页即可,同标签页跳转不需要这步。 - 不需要额外抓包找接口、逆向JS计算规则,保持同一个浏览器会话的操作链路,就不会被网站的重定向规则拦截。
内容的提问来源于stack exchange,提问作者Kelvin Deen
相关产品推荐
相关产品推荐

