如何用C#获取网站动态内容?实战场景问题求助
C# + Selenium 爬取动态页面数据解决方案
问题背景
想用C#程序自动抓取网站中动态加载的信息,这类信息不在页面源码里,浏览器F12也难以直接定位。尝试过NuGet的Selenium包,但未能成功获取目标内容——获取body内容没用(全是动态渲染的),也找不到可用的特定ID选择器。
场景1:物品列表页爬取(含翻页)
目标页面:https://web.idle-mmo.com/wiki/items?page=1&sort_by=id_asc
需求:获取每个物品的名称及对应详情页链接,实现点击按钮翻页到第2页(直接访问第2页链接会跳回第1页)
实现思路
- 使用
WebDriverWait等待页面元素加载完成,避免因动态渲染导致元素找不到 - 通过CSS选择器定位物品项(页面中每个物品是带链接的卡片元素)
- 定位“下一页”按钮,点击实现翻页,重复爬取逻辑
代码示例
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; using System; using System.Collections.Generic; private void ScrapeItemList() { using IWebDriver driver = new ChromeDriver(); WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); driver.Navigate().GoToUrl("https://web.idle-mmo.com/wiki/items?page=1&sort_by=id_asc"); // 爬取当前页物品数据 var itemElements = wait.Until(d => d.FindElements(By.CssSelector("a[href*='/wiki/items/']:has(div[class*='item-name'])"))); List<(string Name, string Url)> items = new List<(string, string)>(); foreach (var item in itemElements) { string itemName = item.FindElement(By.CssSelector("div[class*='item-name']")).Text; string itemUrl = item.GetAttribute("href"); items.Add((itemName, itemUrl)); Console.WriteLine($"物品:{itemName},链接:{itemUrl}"); } // 点击翻页到第2页 try { var nextPageBtn = wait.Until(d => d.FindElement(By.CssSelector("button[aria-label='Go to next page']"))); if (nextPageBtn.Enabled) { nextPageBtn.Click(); // 等待第2页加载完成后可继续爬取 wait.Until(d => d.Url.Contains("page=2")); Console.WriteLine("已跳转到第2页"); } } catch (WebDriverTimeoutException) { Console.WriteLine("找不到下一页按钮或已到最后一页"); } driver.Quit(); }
场景2:物品详情页爬取(销售信息+价格历史)
目标页面:https://web.idle-mmo.com/wiki/items/mystic-sword/ZjlPA8v9NMaXNEyMe2Oa?same_window=true
需求:获取最新销售信息,以及鼠标悬停图表时显示的近几日价格历史
实现思路
- 等待销售信息元素加载,直接定位获取文本
- 对于图表悬停数据,使用
Actions类模拟鼠标悬停到图表的日期点,然后获取弹出的提示文本
代码示例
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Interactions; using OpenQA.Selenium.Support.UI; using System; private void ScrapeItemDetails() { using IWebDriver driver = new ChromeDriver(); WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); driver.Navigate().GoToUrl("https://web.idle-mmo.com/wiki/items/mystic-sword/ZjlPA8v9NMaXNEyMe2Oa?same_window=true"); // 获取最新销售信息 try { var lastSoldInfo = wait.Until(d => d.FindElement(By.CssSelector("div[class*='last-sold']"))); Console.WriteLine("最新销售信息:" + lastSoldInfo.Text); } catch (WebDriverTimeoutException) { Console.WriteLine("未找到最新销售信息"); } // 获取图表悬停的价格历史 try { // 定位图表上的所有数据点 var chartPoints = wait.Until(d => d.FindElements(By.CssSelector("svg g[class*='chart-point']"))); Actions actions = new Actions(driver); foreach (var point in chartPoints) { // 模拟鼠标悬停 actions.MoveToElement(point).Perform(); // 等待提示框出现并获取内容 var tooltip = wait.Until(d => d.FindElement(By.CssSelector("div[class*='tooltip']"))); Console.WriteLine("价格历史:" + tooltip.Text); // 短暂停顿避免操作过快 System.Threading.Thread.Sleep(500); } } catch (WebDriverTimeoutException) { Console.WriteLine("未找到图表或价格历史提示"); } driver.Quit(); }
关键注意事项
- 动态页面必须使用
WebDriverWait等待元素加载,不能直接查找元素,否则会因渲染未完成报错 - CSS选择器可以通过元素的类名片段(用
*=匹配)、层级关系来定位,无需依赖特定ID - 模拟鼠标操作需使用
Actions类,确保触发前端的悬停事件
内容的提问来源于stack exchange,提问作者Ionnae
相关产品推荐
相关产品推荐

