C# 爬虫 抓取小说

心血来潮,想研究下爬虫,爬点小说。

通过百度选择了个小说网站,随便找了一本小书http://www.23us.so/files/article/html/13/13655/index.html

1、分析html规则

思路是获取小说章节目录,循环目录,抓取所有章节中的内容,拼到txt文本中。最后形成完本小说。

1、获取小说章节目录

通过分析,我在标注的地方获取小说名字及章节目录。

<meta name="keywords" content="无疆,无疆最新章节,无疆全文阅读"/>// 获取小说名字
<table cellspacing="1" cellpadding="0" bgcolor="#E4E4E4" id="at">// 所有的章节都在这个table中。

下面是利用正则,获取名字与目录。

// 获取小说名字
Match ma_name = Regex.Match(html, @"<meta name=""keywords"".+content=""(.+)""/>");
string name = ma_name.Groups[1].Value.ToString().Split(',')[0];

// 获取章节目录
Regex reg_mulu = new Regex(@"<table cellspacing=""1"" cellpadding=""0"" bgcolor=""#E4E4E4"" at"">(.|\n)*?</table>");
var mat_mulu = reg_mulu.Match(html);
string mulu = mat_mulu.Groups[0].ToString();

2、获取小说正文内容

通过章节a标签中的url地址,查看章节内容。

通过分析,正文内容在<dd >中。

// 获取正文
Regex reg = new Regex(@"<dd contents"">(.|\n)*?</dd>");
MatchCollection mc = reg.Matches(html_z);
var mat = reg.Match(html_z);
string content = mat.Groups[0].ToString().Replace("<dd id=\"contents\">", "").Replace("</dd>", "").Replace("&nbsp;", "").Replace("<br />", "\r\n");

2、C#完整代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;

namespace Test.Controllers
{
    public class CrawlerController : BaseController
    {
        // GET: Crawler
        public void Index()
        {
            //抓取整本小说
            CrawlerController cra = new CrawlerController();// 顶点抓取小说网站小说
            string html = cra.HttpGet("http://www.23us.so/files/article/html/13/13655/index.html", "");

            // 获取小说名字
            Match ma_name = Regex.Match(html, @"<meta name=""keywords"".+content=""(.+)""/>");
            string name = ma_name.Groups[1].Value.ToString().Split(',')[0];

            // 获取章节目录
            Regex reg_mulu = new Regex(@"<table cellspacing=""1"" cellpadding=""0"" bgcolor=""#E4E4E4"" at"">(.|\n)*?</table>");
            var mat_mulu = reg_mulu.Match(html);
            string mulu = mat_mulu.Groups[0].ToString();

            // 匹配a标签里面的url
            Regex tmpreg = new Regex("<a[^>]+?href=\"([^\"]+)\"[^>]*>([^<]+)</a>", RegexOptions.Compiled);
            MatchCollection sMC = tmpreg.Matches(mulu);
            if (sMC.Count != 0)
            {
                //循环目录url,获取正文内容
                for (int i = 0; i < sMC.Count; i++)
                {
                    //sMC[i].Groups[1].Value
                    //0是<a href="http://www.23us.so/files/article/html/13/13655/5638725.html">第一章 泰山之巅</a> 
                    //1是http://www.23us.so/files/article/html/13/13655/5638725.html
                    //2是第一章 泰山之巅

                    // 获取章节标题
                    string title = sMC[i].Groups[2].Value;

                    // 获取文章内容
                    string html_z = cra.HttpGet(sMC[i].Groups[1].Value, "");

                    // 获取小说名字,章节中也可以查找名字
                    //Match ma_name = Regex.Match(html, @"<meta name=""keywords"".+content=""(.+)"" />");
                    //string name = ma_name.Groups[1].Value.ToString().Split(',')[0];

                    // 获取标题,通过分析h1标签也可以得到章节标题
                    //string title = html_z.Replace("<h1>", "*").Replace("</h1>", "*").Split('*')[1];

                    // 获取正文
                    Regex reg = new Regex(@"<dd contents"">(.|\n)*?</dd>");
                    MatchCollection mc = reg.Matches(html_z);
                    var mat = reg.Match(html_z);
                    string content = mat.Groups[0].ToString().Replace("<dd id=\"contents\">", "").Replace("</dd>", "").Replace("&nbsp;", "").Replace("<br />", "\r\n");
// txt文本输出 string path = AppDomain.CurrentDomain.BaseDirectory.Replace("\\", "/") + "Txt/"; Novel(title + "\r\n" + content, name, path); } } } /// <summary> /// 创建文本 /// </summary> /// <param name="content">内容</param> /// <param name="name">名字</param> /// <param name="path">路径</param> public void Novel(string content, string name, string path) { string Log = content + "\r\n"; // 创建文件夹,如果不存在就创建file文件夹 if (Directory.Exists(path) == false) { Directory.CreateDirectory(path); } // 判断文件是否存在,不存在则创建 if (!System.IO.File.Exists(path + name + ".txt")) { FileStream fs1 = new FileStream(path + name + ".txt", FileMode.Create, FileAccess.Write);// 创建写入文件 StreamWriter sw = new StreamWriter(fs1); sw.WriteLine(Log);// 开始写入值 sw.Close(); fs1.Close(); } else { FileStream fs = new FileStream(path + name + ".txt" + "", FileMode.Append, FileAccess.Write); StreamWriter sr = new StreamWriter(fs); sr.WriteLine(Log);// 开始写入值 sr.Close(); fs.Close(); } } public string HttpPost(string Url, string postDataStr) { CookieContainer cookie = new CookieContainer(); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr); request.CookieContainer = cookie; Stream myRequestStream = request.GetRequestStream(); StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312")); myStreamWriter.Write(postDataStr); myStreamWriter.Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); response.Cookies = cookie.GetCookies(response.ResponseUri); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } public string HttpGet(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); request.Method = "GET"; HttpWebResponse response; request.ContentType = "text/html;charset=UTF-8"; try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { response = (HttpWebResponse)request.GetResponse(); } Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } } }

3、最后效果

 

<think>好的,我现在需要回答用户关于Shmoo测试的问题。首先,用户问的是什么是Shmoo测试,它的原理应用。我需要先理解Shmoo测试的基本概念,然后整理出它的工作原理实际应用场景。 首先,根据提供的引用资料,引用[1]提到Shmoo有助于快速了解故障可能的原因,以及在安装中查找调试的位置。这说明Shmoo测试主要用于芯片测试中的故障分析。接下来,我需要确认Shmoo测试的具体定义,可能需要结合其他资料,但根据现有引用,可以推断Shmoo测试是通过绘制Shmoo来分析芯片在不同电压、频率等参数下的表现,从而找出故障点。 关于原理,Shmoo测试应该涉及参数扫描,比如改变电压或频率,观察芯片的输出是否符合预期。引用[1]提到测试时的失败被分析调试,所以原理可能是在不同条件下测试芯片,生成Shmoo来识别故障模式。 应用方面,引用[1]提到在芯片测试中用于快速定位故障,提高良率。此外,引用[2]提到开路/短路测试帮助诊断测试系统的问题,这可能与Shmoo测试的应用场景相关,比如在测试过程中结合其他测试方法确保设备接触良好,从而准确执行Shmoo测试。 现在需要确保回答结构清晰,分点说明定义、原理应用,并正确引用提供的资料。同时,根据用户要求,生成相关问题,可能需要涉及Shmoo的分析、测试参数、应用领域等。 检查是否需要使用正确的LaTeX格式,比如行内公式用$...$,独立公式用$$...$$。但当前问题不涉及数学公式,可能不需要使用。不过如果有相关参数,比如电压V频率f的关系,可能需要公式,但根据现有资料,暂时不需要。 最后,生成相关问题,要围绕Shmoo测试的原理、应用、与其他测试方法的比较等。</think>### Shmoo测试详解 #### 1. 定义与核心概念 Shmoo测试是一种用于半导体芯片测试形化分析方法,通过扫描芯片的关键参数(如电压、频率、时序等),绘制出反映芯片性能边界的“Shmoo”[^1]。其名称来源于卡通形象“Shmoo”,因其形通常呈现不规则形状而得名。 #### 2. 工作原理 - **参数扫描**:对目标参数进行阶梯式调整,例如: - 供电电压 $V_{DD}$ 从0.8V到1.2V以0.01V步进 - 时钟频率 $f_{CLK}$ 从100MHz到2GHz扫描 - **响应检测**:记录芯片在每个参数组合下的测试结果(通过/失败) - **形绘制**:将测试结果映射为二维或三维形,形成特征区域 典型测试流程: ```text 参数配置 → 测试执行 → 数据采集 → 形生成 → 故障分析 ``` #### 3. 关键应用场景 1. **良率提升**:快速定位参数敏感区域(如电压-频率组合的失效边界) 2. **故障隔离**:识别制造缺陷类型(如时序违例、信号完整性等问题) 3. **可靠性验证**:评估芯片在不同工作条件下的稳定性 4. **测试系统校准**:结合开路/短路测试验证探针接触质量[^2] #### 4. 技术特点对比 | 特性 | Shmoo测试 | 传统功能测试 | |---------------|----------------|---------------| | 诊断粒度 | 晶体管级特性 | 模块级功能 | | 测试数据量 | 百万级数据点 | 千级测试向量 | | 分析维度 | 多参数相互作用 | 单参数验证 | ####
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值