使用HtmlAgilityPack+PuppeteerSharp+iText7抓取IdentityServer4帮助文档

需要学习IdentityServer4的用法,但是在IdentityServer4帮助文档网站(参考文献1)中没有找到下载离线文档的地方,准备使用HtmlAgilityPack+PuppeteerSharp+iText7将网站内容抓取生成离线PDF文档,便于本机学习、查看。
  首先是分析网页结构,下图是帮助文档首页的html中左侧导航菜单的结构,从中可以看到以下几点:
  1)整个导航菜单内容放在类名为wy-menu wy-menu-vertical的div元素内;
  2)导航中一级菜单名称放在类名为caption的p元素内;
  3)一级菜单下的二级菜单紧跟在p元素后,放在ul元素内,ul元素内的所有类名为toctree-l1的li元素内,类名为toctree-l2的li元素内保存的是更下一级的页面内导航,可以忽略。

  根据上述条件,修改之前抓取SqlSugar帮助文档的程序,主要代码及程序运行效果如下所示:

csharp 复制代码
HtmlAgilityPack.HtmlDocument docu = web.Load(txtUrl.Text);
HtmlNode node = docu.DocumentNode.SelectSingleNode(@"//div[@class='wy-menu wy-menu-vertical']");

HtmlNodeCollection tmpNode;
string curClass = string.Empty;

foreach (HtmlNode subNode in node.ChildNodes)
{
    string className = subNode.GetAttributeValue<string>("class", string.Empty);                

    if ((subNode.Name=="p") && (className == "caption"))
    {
        curClass = subNode.InnerText;
    }

    if (subNode.Name== "ul")
    {
        tmpNode = subNode.SelectNodes(".//li[@class='toctree-l1']/a[1]");

        foreach(HtmlNode n in tmpNode)
        {
            m_urls.Add(new LinkInfo { Module = curClass, Name = n.InnerText, Url = @"https://identityserver4.readthedocs.io/en/latest/" + n.Attributes["href"].Value.TrimStart('.') });
            ...
            ...
        }        
    }
}


  接着是生成单个PDF文档的代码及效果:

csharp 复制代码
var options = new LaunchOptions { Headless = true };
using var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(options);

foreach (LinkInfo url in m_urls)
{
    await using var page = await browser.NewPageAsync();
    await page.GoToAsync(url.Url);
    
    PdfOptions option = new PdfOptions();
    option.Format = PuppeteerSharp.Media.PaperFormat.A4;
    option.Landscape = true;

    await page.PdfAsync(Path.Combine(Directory.GetCurrentDirectory() + "\\papers", ($"{url.Module}_{url.Name}.pdf").Replace('/', '_')), option);
    
    await page.DisposeAsync();
}

MessageBox.Show("生成PDF文件结束!");


  最后是调用iText7合并所有PDF文档,生成带书签的IdentityServer4帮助文档的代码及效果。生成的文档已上传到CSDN博客资源中,有需要的可以自行下载。

csharp 复制代码
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(txtFileName.Text));
PdfMerger merger = new PdfMerger(pdfDoc);
merger.SetCloseSourceDocuments(false);

List<PdfFileInfo> pdfFiles = GetSourceDocuments();

foreach (PdfFileInfo doc in pdfFiles)
{
    merger.Merge(doc.docu, 1, doc.docu.GetNumberOfPages());
}

PdfOutline rootOutline = pdfDoc.GetOutlines(false);
PdfOutline tmpOutline = null;
PdfOutline tmpSubOutline = null;
int curPageIndex = 1;
int underlineIndex = -1;
string tmpModule = "XXXXXX";

foreach (PdfFileInfo doc in pdfFiles)
{
    string fileName = doc.FileName;

    if (!fileName.StartsWith(tmpModule))
    {
        underlineIndex = fileName.IndexOf('_');

        tmpModule = fileName.Substring(0, underlineIndex);
        tmpOutline = rootOutline.AddOutline(tmpModule);
        tmpOutline.AddDestination(PdfExplicitDestination.CreateFit(pdfDoc.GetPage(curPageIndex)));
    }

    tmpSubOutline = tmpOutline.AddOutline(fileName.Substring(underlineIndex + 1));
    tmpSubOutline.AddDestination(PdfExplicitDestination.CreateFit(pdfDoc.GetPage(curPageIndex)));
    curPageIndex += doc.docu.GetNumberOfPages();
}

pdfDoc.Close();

foreach (PdfFileInfo doc in pdfFiles)
{
    doc.docu.Close();
}

参考文献:

[1]https://identityserver4.readthedocs.io/en/latest/index.html

[2]https://blog.csdn.net/Gltu_java/article/details/142656171

相关推荐
一坨仙女6 个月前
C#版 iText7——画发票PDF(完整)
pdf·itext7
一坨仙女6 个月前
iText7画发票PDF——小tips
c#·itext7
xkng7 个月前
itext7 PDF添加水印,获取页面高度,添加到页面右上角
java·itext7
一只不秃头的小菜鸟8 个月前
(最新)itext7 freemarker动态模板转pdf
java·itext7·freemarker·html转pdf
gc_229910 个月前
C#使用iText7给PDF文档添加书签
pdf·c#·itext7·书签
gc_229910 个月前
C#使用iText7将多个PDF文档合并为单个文档
pdf·c#·itext7
朱友斌1 年前
【itext7】使用itext7将多个PDF文件、图片合并成一个PDF文件,图片旋转、图片缩放
itext7·itext7合并pdf·itext7操作图片·图片旋转·图片缩放
朱友斌1 年前
【itext7】itext7操作PDF文档之创建PDF文档、加载PDF文档、添加空白页、操作PDF页面、itext中的常见类及其方法
pdf·itext7·itext操作pdf文档·java操作pdf文档·pdfdocument