这一节主要内容是使用正则表达式提取网站的正文,主要面向于小说章节网站。其中涉及到一些其他知识点,比如异步读取、异步流写入等,代码中都会有详细的注解。现在流行的网络文学都是每日一更或几更,没有一个统一的下载入口。以下我将实现一个简单的章节小说下载器的功能,将章节小说以整本的形式下载保存,保守估计能下载网络上70%以上小说。

先看看小说网站的网页源码,天蚕土豆的大主宰第一章。

http://www.biquge.com/4_4606/991334.html 笔趣网

http://www.fqxsw.com/html/11739/4636404.html 番茄小说网

 正文正则

结果发现正文内容一般都是嵌套在div中,样式表可能会略有不同,所以正则表达式可以这样表示

(<div).*</div>

当然有div标签的不一定是正文内容,还有可能是其中不相关的数据。那么按照一般小说的规律,我们指定一个匹配符。

<br\\s*>

只有当匹配符超过5个以上的,我们才认为这是正文内容。

下一页正则

再来找下一页的链接。下一页的链接的格式一般存在两种格式

或是

所以正则表达式可以这样表示

<a.*href=(")(([^<]*[^"])[^>])(\s*)?>.*((→)|(下一页))

异步读取网页流

读取网页数据使用HttpClient异步方法,在读取过程中将主控制权返回到UI层,不会阻塞界面。具体原理请查看我上一篇文章

await httpClient.GetByteArrayAsync(url);

配置文件

为了匹配更多的网站信息,我把正则表达式存在一个ini文件中,在需要的时候可以继续扩充。

核心代码

    private async Task downLoadNovel(byte[] bytes, string url){title = string.Empty;nextPageUrl = string.Empty;content = string.Empty;novelInfo = string.Empty;try{byte[] response = bytes;if (bytes == null){response = await httpClient.GetByteArrayAsync(url);}content = Encoding.Default.GetString(response, 0, response.Length - 1);//获取网页字符编码描述信息   var charSetMatch = Regex.Match(content, "<meta([^<]*)charset=([^<]*)\"", RegexOptions.IgnoreCase | RegexOptions.Multiline);string webCharSet = charSetMatch.Groups[2].Value;if (chartSet == null || chartSet == "")chartSet = webCharSet;if (chartSet != null && chartSet != "" && Encoding.GetEncoding(chartSet) != Encoding.Default)content = Encoding.GetEncoding(chartSet).GetString(response, 0, response.Length - 1);}catch (Exception ex){throw ex;}//小说主域名if (webSiteDomain.Length == 0){var websiteDomainMath = Regex.Match(url, "(http).*(/)", RegexOptions.IgnoreCase);webSiteDomain = websiteDomainMath.Groups[0].Value;}//标题信息var titleInfoMath = Regex.Match(content, "(<title>)([^>]*)(</title>)", RegexOptions.IgnoreCase | RegexOptions.Multiline);title = titleInfoMath.Groups[2].Value;content = content.Replace("'", "\"").Replace("\r\n", "");for (int i = 0; i < contextPatterns.Length; i++){var cpattern = contextPatterns[i];if (novelInfo.Length == 0){    //正文信息var webInfoMath = Regex.Matches(content, cpattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);for (int j = 0; j < webInfoMath.Count; j++){foreach (Group g in webInfoMath[j].Groups){var value = Regex.Split(g.Value, contextNewLine, RegexOptions.IgnoreCase);if (value.Length > 5){novelInfo = g.Value;foreach (var pattern in filterPatterns)novelInfo = Regex.Replace(novelInfo, pattern, new MatchEvaluator(p => null));novelInfo = Regex.Replace(novelInfo, contextNewLine, new MatchEvaluator(p => "\r\n"));break;}}}}elsebreak;}bytes = null;for (int i = 0; i < nextPagePatterns.Length; i++){if (nextPageUrl.Length == 0){//下一页信息var webNextPageMath = Regex.Match(content, nextPagePatterns[i], RegexOptions.IgnoreCase | RegexOptions.Multiline);if (webNextPageMath.Groups.Count > 0){foreach (Group g in webNextPageMath.Groups){if (!g.Value.EndsWith("\""))nextPageUrl = g.Value;if (nextPageUrl.StartsWith("/"))nextPageUrl = nextPageUrl.Substring(1);if (!nextPageUrl.StartsWith("http", true, null) && (Regex.IsMatch(nextPageUrl, "[a-z]") || Regex.IsMatch(nextPageUrl, "[0-9]")) && !url.EndsWith(nextPageUrl)){nextPageUrl = webSiteDomain + nextPageUrl;}try{bytes = await httpClient.GetByteArrayAsync(nextPageUrl);break;}catch{continue;}}}}elsebreak;}bool isAdd = false;cacheNovel.ForEach(p =>{if (p == (title + novelInfo)){isAdd = true;}});if (!isAdd){if (title.Length > 0){writeNovelLog("正在下载章节:" + title);}writeNovelLog("章节长度:" + novelInfo.Length);cacheNovel.Add(title + novelInfo);if (nextPageUrl.Length > 0){writeNovelLog("下一页:" + nextPageUrl);await downLoadNovel(bytes, nextPageUrl);}else{downloadFinish();}}else{writeNovelLog("存在重复的章节,章节名称:" + title + " 地址:" + url);downloadFinish();}}

异步下载网页流、解析数据

最后效果

转载于:https://www.cnblogs.com/yzp12sina/p/3520321.html

c# 使用正则表达式 提取章节小说正文全本篇相关推荐

  1. python爬虫小说代码示例-Python从零开始写爬虫-4 解析HTML获取小说正文

    Python从零开始写爬虫-4 解析HTML获取小说正文 在上一节中, 我们已经学会如何获取小说的目录, 这一节我们将学习如何通过正则表达式(在第二节学习过)来获取小说正文. 首先, 先随便选择一个章 ...

  2. Python lxml库 提取并保存网页正文部分

    有时候, 看见一篇网页, 不知道怎样离线保存.使用浏览器的保存网页功能, 又会保存下许多无用的信息, 如广告等其他部分. 为解决这个问题, 本程序使用requests库获取网页源代码, 使用re模块及 ...

  3. Jmeter的使用-接口调用、正则表达式提取器、beanshell断言、http信息头管理器

    Jmeter的使用----接口调用.正则表达式提取器.beanshell断言.http信息头管理器. 前几天看到有关幂等的的概念,对于比较重要的业务,如何保证接口的幂等至关重要,网上看到了许多解决方案 ...

  4. Jmeter工具中参数化、正则表达式提取器、响应断言的实现

    参数化.正则表达式提取器.响应断言的实现 1.实现参数化 2.正则表达式提取器 3.响应断言 上一篇文章实现了用Jmeter工具实现了新增用户和学员登录两个功能,这篇文章将对前两个功能进行优化. 1. ...

  5. 爬虫 | 正则表达式提取腾讯教育新闻链接及图片链接

    前面的爬虫都是通过标签来爬取的,今天就分享一个小例子使用正则表达式来提取网页信息.如果你对正则表达式不熟悉,可以查看我之前写的R正则表达式这篇文章.它对R几个常用正则表达式进行了详尽的解释,包括参数说 ...

  6. jmeter全局变量传参_Jmeter 将正则表达式提取的参数传给全局(跨线程组使用变量)...

    一.使用正则表达式提取sessionId 1.在测试计划(跨线程组使用变量)--> 线程组(登录)--> 添加HTTP请求(登录接口) (1)创建测试计划: 勾选独立运行每个线程组(例如在 ...

  7. C#正则表达式提取文本中以逗号间隔的数据

    使用正则表达式提取文本数据到内存是很方便的技术,下面通过一个例子介绍一下如何使用正则表达式提取文本 文本中内容格式 1,2,3,4,5 2,2,2,2,2 3,3,3,3,3 C#代码如下 publi ...

  8. C#正则表达式提取HTML中IMG标签的SRC地址(转)

    一般来说一个 HTML 文档有很多标签,比如"<html>"."<body>"."<table>"等,想 ...

  9. 在python中,用正则表达式提取多层括号中最外层括号包含的内容

    提取多层括号中最外层括号包含的内容有几种方式,那么用正则表达式该怎么实现呢? 在python中,用正则表达式提取多层括号中最外层括号包含的内容 比如有一个字符串 : 学习python中有什么不懂的地方 ...

  10. jmeter正则表达式提取器多模块相互调用

    提取return的结果 (1)例: 创建账户和转账功能 注:以下为soap协议 添加账户1 创建正则表达式提取器(提取创建的结果) 点击导入接口文档URL地址和方框内方法 同上方法添加账户2 点击正则 ...

最新文章

  1. folders默认配置 shell_分布式存储Ceph RBD-Mirror灾备方案(二)镜像模式配置
  2. 如何构建优雅的ViewController
  3. 栈劫持(栈迁移)介绍
  4. bean.xml配置数据源和读取配置文件配置数据源
  5. $.ajax()参数详解及标准写法
  6. javascript动态创建table
  7. malloc()和calloc()有啥区别
  8. 网络安全系列之四十 在Linux中设置SET位权限
  9. android 多次点击事件,Android按钮onclick事件在多次单击后激发
  10. github开源的流程-慕课网教程学习笔记
  11. FLASH右键菜单的应用
  12. maya界面字体大小修改方法
  13. 【Graph Embedding】node2vec:算法原理,实现和应用
  14. Spring STS 修改启动Java VM
  15. TeamViewer远程连接控制软件
  16. win10--ubuntu 16.04桌面共享
  17. typescript元组
  18. 京东云首次发布数智供应链全景图 锚定产业数字化新赛道
  19. win10自带邮件mail登录qq邮箱126邮箱等时提示需注意的解决办法
  20. Android 7.1 亮度调节之BrightnessController

热门文章

  1. 计算机桌面全部内容自定义,电脑win10如何恢复自定义桌面图标排列的方法
  2. C语言CGI编程入门(一)
  3. LibreELEC(kodi)安装
  4. 将中文转化为GB2312编码
  5. 微信小程序-tab切换(scroll-view + swiper)
  6. _stdcall,_cdecl区别
  7. 未来教育计算机二级题库如何更新,未来教育的计算机二级题库准吗?
  8. 计算机三级-未来教育考试题库做完题不显示正确与否解决办法
  9. MSVCR71.dll is missing from your computer-(Window7 install sqldeveloper for oracle )
  10. 如何解决Mac电脑键盘上的大写锁定键灯不亮?