C#爬取动态网页上的信息:B站主页
简介
动态内容网站使用 JavaScript 脚本动态检索和渲染数据,爬取信息时需要模拟浏览器行为,否则获取到的源码基本是空的。爬取步骤如下:
- 使用 Selenium 获取渲染后的 HTML 文档
- 使用 HtmlAgilityPack 解析 HTML 文档
新建项目,安装需要的库:
- Selenium.WebDriver
- HtmlAgilityPack
获取 HTML 文档
需要注意的主要是以下2点:
- 设置浏览器启动参数:无头模式、禁用GPU加速、设置启动时窗口大小
- 等待页面动态加载完成:等待5秒钟,设置一个合适的时间即可
private static string GetHtml(string url)
{
    ChromeOptions options = new ChromeOptions();
    // 不显示浏览器
    options.AddArgument("--headless");
    // GPU加速可能会导致Chrome出现黑屏及CPU占用率过高
    options.AddArgument("--nogpu");
    // 设置chrome启动时size大小
    options.AddArgument("--window-size=10,10");
    using (var driver = new ChromeDriver(options))
    {
        try
        {
            driver.Manage().Window.Minimize();
            driver.Navigate().GoToUrl(url);
            // 等待页面动态加载完成
            Thread.Sleep(5000);
            // 返回页面源码
            return driver.PageSource;
        }
        catch (NoSuchElementException)
        {
            Console.WriteLine("找不到该元素");
            return string.Empty;
        }
    }
}
解析 HTML 文档
这里以B站为例,爬取B站UP主主页上的视频信息,如视频的标题、链接、封面。
先定义一个类来保存信息:
class VideoInfo
{
    public string Title { get; set; }
    public string Href { get; set; }
    public string ImgUrl { get; set; }
}
定义解析函数,返回视频信息列表:
private static List<VideoInfo> GetVideoInfos(string url)
{
    List<VideoInfo> videoInfos = new List<VideoInfo>();
    // 加载文档
    var html = GetHtml(url);
    var htmlDoc = new HtmlDocument();
    htmlDoc.LoadHtml(html);
    // 解析文档,先定位到视频列表标签
    var xpath = "/html/body/div[2]/div[4]/div/div/div[1]/div[2]/div/div";
    var htmlNodes = htmlDoc.DocumentNode.SelectNodes(xpath);
    // 循环解析它的子节点视频信息
    foreach (var node in htmlNodes)
    {
        var titleNode = node.SelectSingleNode("a[2]");
        var imgNode = node.SelectSingleNode("a[1]/div[1]/picture/source[1]");
        var title = titleNode.InnerText;
        var href = titleNode.Attributes["href"].Value.Trim('/');
        var imgUrl = imgNode.Attributes["srcset"].Value.Split('@')[0].Trim('/');
        videoInfos.Add(new VideoInfo
        {
            Title = title,
            Href = href,
            ImgUrl = imgUrl
        });
    }
    return videoInfos;
}
视频列表标签的 XPath 路径是通过浏览器调试工具,在指定标签上右键 复制完整的XPath 得到:

分析代码中的 node 节点时,html文本格式可能很乱,可以通过在线 HTML 代码格式化 工具格式后再进行分析。
测试
以B站UP主 星瞳_Official 为例,爬取视频信息:
static void Main(string[] args)
{
    var url = @"https://space.bilibili.com/401315430";
    var videoInfos = GetVideoInfos(url);
    foreach (var videoInfo in videoInfos)
    {
        Console.WriteLine(videoInfo.Title);
        Console.WriteLine(videoInfo.Href);
        Console.WriteLine(videoInfo.ImgUrl);
        Console.WriteLine();
    }
    Console.ReadKey();
}
结果如下:
等一下,好妹妹
www.bilibili.com/video/BV1uyxLeJEM9
i0.hdslb.com/bfs/archive/46a15065d1b6722a04696ffaaa2235287ceaa452.jpg
一口一个?你的超甜辣椒
www.bilibili.com/video/BV1AQsDeiEn1
i0.hdslb.com/bfs/archive/d93d47d67323ee284483e963ffed34fb9884cf61.jpg
这里只是演示爬取动态页面的方法,如果想获取B站UP主的视频信息,建议直接使用 API 请求数据。
参考文章
C#爬取动态网页上的信息:B站主页的更多相关文章
- R语言爬取动态网页之环境准备
		在R实现pm2.5地图数据展示文章中,使用rvest包实现了静态页面的数据抓取,然而rvest只能抓取静态网页,而诸如ajax异步加载的动态网页结构无能为力.在R语言中,爬取这类网页可以使用RSele ... 
- 记录几个爬取动态网页时的问题(下拉框,旧的元素无法获取,获取的源代码和f12看到的不一致,爬取延迟)
		更新.....这个动态网页其实直接抓取ajax请求就可以了,很简单,我之前想复杂了,虽然也实现了,但是效率极低,不过没关系,就当作是对Selenium的一次学习吧 1.最近在爬取一个动态网页,其中为了 ... 
- python爬取动态网页数据,详解
		原理:动态网页,即用js代码实现动态加载数据,就是可以根据用户的行为,自动访问服务器请求数据,重点就是:请求数据,那么怎么用python获取这个数据了? 浏览器请求数据方式:浏览器向服务器的api(例 ... 
- 爬虫(三)通过Selenium + Headless Chrome爬取动态网页
		一.Selenium Selenium是一个用于Web应用程序测试的工具,它可以在各种浏览器中运行,包括Chrome,Safari,Firefox 等主流界面式浏览器. 我们可以直接用pip inst ... 
- 利用selenium并使用gevent爬取动态网页数据
		首先要下载相应的库 gevent协程库:pip install gevent selenium模拟浏览器访问库:pip install selenium selenium库相应驱动配置 https: ... 
- 爬取动态网页:Selenium
		参考:http://blog.csdn.net/wgyscsf/article/details/53454910 概述 在爬虫过程中,一般情况下都是直接解析html源码进行分析解析即可.但是,有一种情 ... 
- python爬取动态网页2,从JavaScript文件读取内容
		import requests import json head = {"user-agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) ... 
- nodejs爬虫笔记(三)---爬取YouTube网站上的视频信息
		思路:通过笔记(二)中代理的设置,已经可以对YouTube的信息进行爬取了,这几天想着爬取网站下的视频信息.通过分析YouTube,发现可以从订阅号入手,先选择几个订阅号,然后爬取订阅号里面的视频分类 ... 
- Python+Selenium爬取动态加载页面(2)
		注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ... 
- Python+Selenium爬取动态加载页面(1)
		注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ... 
随机推荐
- vue小知识~注入provide!
			注入表示的是将该组件的相关值,方法,实例向后代组件注入. 祖先元素中定义注入: export default { provide() { return { provideName: provideVa ... 
- Django model 层之Models与Mysql数据库小结
			Django model 层之Models与Mysql数据库小结 by:授客 QQ:1033553122 测试环境: Python版本:python-3.4.0.amd64 下载地址:https:// ... 
- 单细胞测序最好的教程(九): 细胞类型自动注释|发表在Science的注释算法
			作者按 本章节主要讲解了基于大模型的自动注释方法,包括CellTypist(发表在Science)和MetaTiME(发表在Nature communication),一个通用,一个泛癌专用.本教程首 ... 
- 大语言模型(LLM)运行报错:AttributeError: module 'streamlit' has no attribute 'cache_resource'
			解决方法: https://blog.csdn.net/javastart/article/details/130785100 (图:https://blog.csdn.net/javastart/a ... 
- pytorch  第三方模块    GraphNAS    安装成功记录
			实验室的小师妹要安装pytorch的第三方模块,经过多方努力没有安装上,后来我接手后也是感觉头疼. 该模块地址: https://github.com/GraphNAS/GraphNAS 该模块主 ... 
- 一个好主板对CPU超频的现实意义————一次超频经历  (z390ws华硕工作站主板+i7-9700k CPU ,Ubuntu18.04.5系统,8核心超频 5.2Ghz以上,单核心满负荷运转可以稳定运行10多分钟后才重启)
			本人于今年2020年1月份在某宝上购买了一款workstation主板,也就是工作站主板,传说中的华硕Z390WS主板(购入价格为3900元),由于当时手里有些小钱,又弄了一个大蝴蝶1350w的电源( ... 
- 【转载】   gym atari游戏的环境设置问题:Breakout-v0, Breakout-v4, BreakoutNoFrameskip-v4和BreakoutDeterministic-v4的区别
			版权声明:本文为CSDN博主「ok_kakaka」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/clksjx/ ... 
- 国产计算框架mindspore在gpu环境下1.3.0版本的分布式计算组件安装  ——(openmpi 和 nccl 的安装,配置,示例代码的运行)
			前文已经给出1.3.0gpu版本的编译及安装,本文在此基础上进行分布式组件的安装,前文信息参看: 国产计算框架mindspore在gpu环境下编译分支r1.3,使用suod权限成功编译并安装,成功运行 ... 
- 深度解读KubeEdge架构设计与边缘AI实践探索
			摘要:解读业界首个云原生边缘计算框架KubeEdge的架构设计,如何实现边云协同AI,将AI能力无缝下沉至边缘,让AI赋能边侧各行各业,构建智能.高效.自治的边缘计算新时代,共同探索智能边缘的新篇章. ... 
- 如何用python做一个简单的小游戏 Pygame
			当然可以!下面是一个简单的Python游戏开发教程,帮助你入门: 安装Pygame库 Pygame是一个Python游戏开发库,可以帮助你创建游戏窗口.绘制图形.处理用户输入等.你可以使用以下命令在命 ... 
