浏览器(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("生成成功");
}
目录
相关文章
|
2月前
|
Web App开发 小程序 前端开发
【产品上新】小程序新内核来了!提升安卓浏览器性能,支持WebRTC
【产品上新】小程序新内核来了!提升安卓浏览器性能,支持WebRTC
36 0
|
6月前
|
Web App开发 前端开发 JavaScript
|
5月前
|
Web App开发
自制浏览器网页背景是什么体验?
自制浏览器网页背景是什么体验?
45 0
|
前端开发 JavaScript
web浏览器常用内核和web标准
web浏览器常用内核和web标准
web浏览器常用内核和web标准
|
移动开发 前端开发 JavaScript
WebKit 技术内幕之浏览器与WebKit内核
此文章是我最近在看的【WebKit 技术内幕】一书的一些理解和做的笔记。 而【WebKit 技术内幕】是基于 WebKit 的 Chromium 项目的讲解。
479 0
WebKit 技术内幕之浏览器与WebKit内核
|
前端开发 JavaScript Java
websocket部署后在谷歌内核浏览器异常断开问题
后端springboot前端vue开发的网页,利用websocket实现操作数据库前端网页实时刷新的功能
websocket部署后在谷歌内核浏览器异常断开问题
|
Web App开发 缓存 前端开发
火狐 和 谷歌Google Chrome 内核浏览器 跨域问题
火狐 和 谷歌Google Chrome 内核浏览器 跨域问题
240 0
|
数据采集 Web App开发 JavaScript
浏览器(2):自制Chromium内核浏览器,自动统计CSDN社区打卡记录(二)
自研、掌握核心科技?这我可不敢吹,我老老实实说我用了个Chromium内核组件。 为了统计一些数据,一条条复制粘贴肯定是够累的。用爬虫吧,自己还不精通,而且现在好多数据都需要登录才能请求,或者有些需要滑滚动条才显示。 比如csdn社区的打卡记录,一个月的如何快速的统计出来呢?
539 0
浏览器(2):自制Chromium内核浏览器,自动统计CSDN社区打卡记录(二)
|
28天前
|
存储 机器人
在阿里云RPA中,你可以通过以下步骤来更改默认唤醒IE浏览器的地址
【2月更文挑战第28天】在阿里云RPA中,你可以通过以下步骤来更改默认唤醒IE浏览器的地址
17 1