这一节主要内容是使用正则表达式提取网站的正文,主要面向于小说章节网站。其中涉及到一些其他知识点,比如异步读取、异步流写入等,代码中都会有详细的注解。现在流行的网络文学都是每日一更或几更,没有一个统一的下载入口。以下我将实现一个简单的章节小说下载器的功能,将章节小说以整本的形式下载保存,保守估计能下载网络上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, , response.Length - );
//获取网页字符编码描述信息
var charSetMatch = Regex.Match(content, "<meta([^<]*)charset=([^<]*)\"", RegexOptions.IgnoreCase | RegexOptions.Multiline); string webCharSet = charSetMatch.Groups[].Value;
if (chartSet == null || chartSet == "")
chartSet = webCharSet; if (chartSet != null && chartSet != "" && Encoding.GetEncoding(chartSet) != Encoding.Default)
content = Encoding.GetEncoding(chartSet).GetString(response, , response.Length - );
}
catch (Exception ex)
{
throw ex;
}
//小说主域名
if (webSiteDomain.Length == )
{
var websiteDomainMath = Regex.Match(url, "(http).*(/)", RegexOptions.IgnoreCase);
webSiteDomain = websiteDomainMath.Groups[].Value;
} //标题信息
var titleInfoMath = Regex.Match(content, "(<title>)([^>]*)(</title>)", RegexOptions.IgnoreCase | RegexOptions.Multiline);
title = titleInfoMath.Groups[].Value; content = content.Replace("'", "\"").Replace("\r\n", ""); for (int i = ; i < contextPatterns.Length; i++)
{
var cpattern = contextPatterns[i];
if (novelInfo.Length == )
{
//正文信息
var webInfoMath = Regex.Matches(content, cpattern, RegexOptions.IgnoreCase | RegexOptions.Multiline); for (int j = ; j < webInfoMath.Count; j++)
{
foreach (Group g in webInfoMath[j].Groups)
{
var value = Regex.Split(g.Value, contextNewLine, RegexOptions.IgnoreCase);
if (value.Length > )
{
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;
}
}
} }
else
break;
} bytes = null; for (int i = ; i < nextPagePatterns.Length; i++)
{
if (nextPageUrl.Length == )
{
//下一页信息
var webNextPageMath = Regex.Match(content, nextPagePatterns[i], RegexOptions.IgnoreCase | RegexOptions.Multiline);
if (webNextPageMath.Groups.Count > )
{
foreach (Group g in webNextPageMath.Groups)
{
if (!g.Value.EndsWith("\""))
nextPageUrl = g.Value;
if (nextPageUrl.StartsWith("/"))
nextPageUrl = nextPageUrl.Substring();
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;
}
} }
}
else
break;
}
bool isAdd = false;
cacheNovel.ForEach(p =>
{
if (p == (title + novelInfo))
{
isAdd = true;
}
}); if (!isAdd)
{
if (title.Length > )
{
writeNovelLog("正在下载章节:" + title);
} writeNovelLog("章节长度:" + novelInfo.Length); cacheNovel.Add(title + novelInfo); if (nextPageUrl.Length > )
{
writeNovelLog("下一页:" + nextPageUrl); await downLoadNovel(bytes, nextPageUrl);
}
else
{
downloadFinish();
}
}
else
{
writeNovelLog("存在重复的章节,章节名称:" + title + " 地址:" + url);
downloadFinish();
}
}

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

最后效果

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

  1. 将RegEx(正则表达式提取器)与JMeter一起使用

    JMeter的,最流行的开源性能测试工具,可以工作正则表达式,用正则表达式提取.正则表达式是一种用于通过使用高级操作提取文本的必需部分的工具.正则表达式在测试Web应用程序时很流行,因为它们可用于验证 ...

  2. JMeter中的关联-正则表达式提取(2)

    JMeter获取正则表达式中的提取的所有关联值的解决方法: 需求如下: { : ", : "results": : [ : : { : : : "total_e ...

  3. JMeter中的关联-正则表达式提取(1)

    运用Jmeter正则提取器,可以从请求的响应结果中取到需要的内容,从而实现关联. jmeter之关联 的个人理解: 关联是请求与请求之间存在数据依赖关系,需要从上一个请求获取下一个请求需要回传回去的数 ...

  4. asp.net正则表达式提取网页网址、标题、图片实例以及过滤所有HTML标签实例

    无论你用什么语言,正则表达式的处理方法都是非常灵活.高效的,尤其是对某些字符串的抓取.过滤方面,更显其优势. 正则表达式的写法通常比较简单,几行短代码便能轻松完成看似很复杂的事情,更值得称赞的是,它的 ...

  5. Jmeter—5 关联 响应数据传递-正则表达式提取器

    在测试过程中,遇到一个问题:用户登录成功后服务器会返回一个登录凭证,之后所有的操作都需要带上此凭证.我们怎么获取登录凭证并传递给后续的操作? Jmeter提供了正则表达式提取器,用变量提取参数,后续通 ...

  6. JMeter学习-011-JMeter 后置处理器实例之 - 正则表达式提取器(三)多参数获取进阶引用篇

    前两篇文章分表讲述了 后置处理器 - 正则表达式提取器概述及简单实例.多参数获取,相应博文敬请参阅 简单实例.多参数获取. 此文主要讲述如何引用正则表达式提取器获取的数据信息.其实,正则表达式提取器获 ...

  7. JMeter学习-009-JMeter 后置处理器实例之 - 正则表达式提取器(二)多参数获取

    前文简述了通过后置处理器 - 正则表达式提取器 获取 HTTP请求 响应结果中的特定数据,未看过的亲,敬请参阅 JMeter学习-008-JMeter 后置处理器实例之 - 正则表达式提取器(一). ...

  8. JMeter学习-008-JMeter 后置处理器实例之 - 正则表达式提取器(一)概述及简单实例

    上文我们讲述了如何对 HTTP请求 的响应数据进行断言,以判断响应是否符合我们的预期,敬请参阅:JMeter学习-007-JMeter 断言实例之一 - 响应断言 那么我们如何获取 HTTP请求 响应 ...

  9. Jmeter正则表达式提取器的使用方法(转)

    下面简单介绍一下Jmeter正则表达式提取器的使用方法. 1.添加Jmeter正则表达式提取器:在具体的Request下添加Jmeter正则表达式提取器(Jmeter正则表达式在“后置处理器”下面)  ...

随机推荐

  1. iOS设备屏幕像素总览

    本文永久地址为http://www.cnblogs.com/ChenYilong/p/4011728.html ,转载请注明出处.   本文永久地址为http://www.cnblogs.com/Ch ...

  2. MBProgressHUD使用

    //方式1.直接在View上show HUD = [[MBProgressHUD showHUDAddedTo:self.view animated:YES] retain]; HUD.delegat ...

  3. 发个题目坑 二模03day1

    1.数列(seq2.pas/c/cpp) 题目描述 一个数列定义如下:f(1) = 1,f(2) = 1,f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.给定 A ...

  4. HTML控件ID和NAME属性及在CS页面获得.ASPX页面中HTML控件的值

    <转载>来自网络 一.ID是在客户端脚本里用!NAME是用于获取提交表单的某表单域信息,在form里面,如果不指定Name的话,就不会发送到服务器端,所以有name属性的控件,必须指定na ...

  5. Sybase IQ导出文件的几种方式

    IQ有四种方法,将表的数据导出为文本文件:1.重定向 SELECT * FROM TABLE1 ># D:MYDATATABLE1.TXT -- 文件生成在执行语句的客户端上 2.通过选项导出 ...

  6. 玩转ubuntu FAQ

    一.用wubi安装ubuntu的时候自动重新下载 1.双击ubuntu.ios让windows加载这个镜像 2.断开网络 二.安装其他程序时提示Error: Dependency is not sat ...

  7. PHP 调试用函数

    2014年7月4日 10:27:59 有些系统函数可以在调试程序时救急用: get_class_methods(); get_class_vars(); get_object_vars(); get_ ...

  8. maven的一些依赖

    maven的一些依赖: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://w ...

  9. [Android Pro] Android fastboot刷机和获取Root权限

    参考文章: https://developers.google.com/android/nexus/images 转载自:    http://www.inexus.co/article-1280-1 ...

  10. 支持向量机(SVM)简介

    主要内容 一:SVM简介 二:线性分类 三:分类间隔 四:核函数 五:松弛变量 SVM简介 支持向量机(support vector Machine)是由Cortes和Vapnik于1995年首先提出 ...