浏览器(2):自制Chromium内核浏览器,自动统计CSDN社区打卡记录(三)

简介: 自研、掌握核心科技?这我可不敢吹,我老老实实说我用了个Chromium内核组件。 为了统计一些数据,一条条复制粘贴肯定是够累的。用爬虫吧,自己还不精通,而且现在好多数据都需要登录才能请求,或者有些需要滑滚动条才显示。 比如csdn社区的打卡记录,一个月的如何快速的统计出来呢?

3. 1 获取所有打卡贴

首先关键字搜索,获取打卡贴列表

// 获取所有链接的JS
string script = @"Array.from(document.getElementsByClassName('user-tabs user-tabs-search')[0].getElementsByClassName('long-text-title')).map(x => ( x.href));";
// 执行JS代码,返回一个JavascriptResponse
JavascriptResponse response1 = await browser.EvaluateScriptAsync(script);
dynamic arr = response1.Result;
// 遍历结果集合,将所有URL存储到一个静态集合中
foreach (dynamic row in arr)
{
  RecordManager.Urls.Add(row.ToString());
}

为了直观,弹出一个对话框,将URL显示出来:

GetCSDN getCSDN = new GetCSDN();
getCSDN.browser = browser;
getCSDN.ShowDialog();

76.png

这里定义了一个静态类来控制分析操作。

    public static class RecordManager
    {
        // 是否开始分析
        public static bool IsStart { get; set; } = false;
        // 分析到第几页
        public static int Index { get; set; } = -1;
        // 获取下一页地址
        public static string GetNextUrl()
        { 
            Index = Index + 1;
            if (Urls.Count == Index)
            {
                return "";
            }
            return Urls[Index];
        }
        // URL列表
        public static List<string> Urls = new List<string>();
        // 获取到的打卡记录列表
        public static List<Record> RecordList { get; set; } = new List<Record>();
        // 分析完之后的回调函数
        public static Action callback;
    }

3.2 逐一打开各个页面并获取结果

上一图右边做了个开始按钮,点击将逐一开始分析。

系统提供了多种Handler用于浏览器各种操作的处理,这里要分析请求操作,所以用到RequestHandler

    public class CustomRequestHandler: RequestHandler
    {
        protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
        {
            return new CustomResourceRequestHandler();
        }
    }

主要是指定了另一个专门用于处理请求的CustomResourceRequestHandler,二者关系如下图,后者才是分析的主角:

77.png

 public class CustomResourceRequestHandler : ResourceRequestHandler
 {
        private readonly MemoryStream memoryStream = new MemoryStream();
        protected override IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
        {
            // 将请求响应结果放到MemoryStream中
            return new CefSharp.ResponseFilter.StreamResponseFilter(memoryStream);
        }
        protected override void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
        {
            // 只分析打卡列表的请求结果
            if (!RecordManager.IsStart || !(request.Url.ToLower().StartsWith("https://bizapi.csdn.net/community-cloud/v1/community/task/list") && request.Method.ToLower().Equals("get")))
            {
                return;
            }
            var bytes = memoryStream.ToArray();
            string pages = string.Empty;
            string page = request.Url.Substring(request.Url.IndexOf("page=") + 5, 1);
            var str = System.Text.Encoding.UTF8.GetString(bytes);
            JObject obj = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(str);
            List<Record> list = (List<Record>)obj["data"]["finish"]["list"].ToObject(typeof(List<Record>));
            pages = obj["data"]["finish"]["pages"].ToString();
            if (list.Count > 0)
            {
                RecordManager.RecordList.AddRange(list);
            }
            if (pages.Equals(page))
            {
                string url = RecordManager.GetNextUrl();
                if (string.IsNullOrEmpty(url))
                {
                    RecordManager.callback();
                }
                else
                {
                    // 休息5秒,再请求下一篇文章
                    Thread.Sleep(5000);
                    browser.MainFrame.LoadUrl(url);
                }
            }
            else
            {
                // 休息5秒,再请求下一页
                Thread.Sleep(5000);
                string js = $"document.getElementsByClassName('number')[{int.Parse( page)}].click();";
                browser.MainFrame.ExecuteJavaScriptAsync(js);
            }
        }
    }

3.3 展示结果

78.png

3.4 导出结果

讲结果导出到Excel:

//创建工作薄
var workbook = new HSSFWorkbook();
//创建表
var table = workbook.CreateSheet("data");
int i = 0;
RecordManager.RecordList.ForEach(record => {
    var row = table.CreateRow(i);
    var cell = row.CreateCell(0);
    cell.SetCellValue(record.finishTime);
    var cell1 = row.CreateCell(1);
    cell1.SetCellValue(record.userName);
    var cell2 = row.CreateCell(2);
    cell2.SetCellValue(record.nickName);
    i++;
});
using (var fs = File.OpenWrite(@"d:/test/1.xls"))
{
    workbook.Write(fs);   //向打开的这个xls文件中写入mySheet表并保存。
    Console.WriteLine("生成成功");
}
目录
相关文章
|
6月前
|
存储 监控 安全
360 企业安全浏览器基于阿里云数据库 SelectDB 版内核 Apache Doris 的数据架构升级实践
为了提供更好的日志数据服务,360 企业安全浏览器设计了统一运维管理平台,并引入 Apache Doris 替代了 Elasticsearch,实现日志检索与报表分析架构的统一,同时依赖 Doris 优异性能,聚合分析效率呈数量级提升、存储成本下降 60%....为日志数据的可视化和价值发挥提供了坚实的基础。
360 企业安全浏览器基于阿里云数据库 SelectDB 版内核 Apache Doris 的数据架构升级实践
|
6月前
|
Web App开发 小程序 前端开发
【产品上新】小程序新内核来了!提升安卓浏览器性能,支持WebRTC
【产品上新】小程序新内核来了!提升安卓浏览器性能,支持WebRTC
119 10
|
Web App开发 前端开发 JavaScript
|
5月前
|
JavaScript 前端开发
WebView2 控件(基于 Microsoft Edge (Chromium) 的嵌入式浏览器控件),获取网页加载后的标题
在使用 WebView2 控件(基于 Microsoft Edge (Chromium) 的嵌入式浏览器控件)时,要获取网页加载后的标题,可以监听 WebView2 的 NavigationCompleted 事件。这个事件被触发时,表示导航已完成,此时执行JavaScript代码可以安全地获取网页的标题。
WebView2 控件(基于 Microsoft Edge (Chromium) 的嵌入式浏览器控件),获取网页加载后的标题
|
4月前
|
Web App开发 编解码
软件开发常见流程之兼容性和手机屏页面设计,PC端和移动端常见浏览器,国内的UC都是根据Webkit修改过来的内核,开发重点关注尺寸,常见移动端尺寸汇总,移动端,理想视口根据你设别的样式进行修改
软件开发常见流程之兼容性和手机屏页面设计,PC端和移动端常见浏览器,国内的UC都是根据Webkit修改过来的内核,开发重点关注尺寸,常见移动端尺寸汇总,移动端,理想视口根据你设别的样式进行修改
|
6月前
|
人工智能 搜索推荐 Linux
一个集 AI + 工具 + 插件 + 社区为一体的Arc 浏览器风格AI客户端
一个集 AI + 工具 + 插件 + 社区为一体的Arc 浏览器风格AI客户端
276 0
|
Web App开发
自制浏览器网页背景是什么体验?
自制浏览器网页背景是什么体验?
74 0
|
IDE 编译器 程序员
CSDN推出【云IDE】,几秒完成开发环境配置,今后可以在浏览器里使用VS Code了
CSDN推出【云IDE】,几秒完成开发环境配置,今后可以在浏览器里使用VS Code了
208 0
CSDN推出【云IDE】,几秒完成开发环境配置,今后可以在浏览器里使用VS Code了
|
前端开发 JavaScript
web浏览器常用内核和web标准
web浏览器常用内核和web标准
121 0
web浏览器常用内核和web标准
|
13天前
|
JSON 移动开发 JavaScript
在浏览器执行js脚本的两种方式
【10月更文挑战第20天】本文介绍了在浏览器中执行HTTP请求的两种方式:`fetch`和`XMLHttpRequest`。`fetch`支持GET和POST请求,返回Promise对象,可以方便地处理异步操作。`XMLHttpRequest`则通过回调函数处理请求结果,适用于需要兼容旧浏览器的场景。文中还提供了具体的代码示例。
在浏览器执行js脚本的两种方式