C# 爬虫 抓取小说
心血来潮,想爬点小说。通过百度选择了个小说网站,随便找了一本小说http://www.23us.so/files/article/html/13/13655/index.html。
1、分析html规则
思路是获取小说章节目录,循环目录,抓取所有章节中的内容,拼到txt文本中。最后形成完本小说。
1、获取小说章节目录

通过分析,我在标注的地方获取小说名字及章节目录。
<meta name="keywords" content="无疆,无疆最新章节,无疆全文阅读"/>// 获取小说名字
<table cellspacing="" cellpadding="" bgcolor="#E4E4E4" id="at">// 所有的章节都在这个table中。
下面是利用正则,获取名字与目录。
//获取小说名字
Match ma_name = Regex.Match(html, @"<meta name=""keywords"".+content=""(.+)""/>");
string name = ma_name.Groups[].Value.ToString().Split(',')[]; //获取章节目录
Regex reg_mulu = new Regex(@"<table cellspacing=""1"" cellpadding=""0"" bgcolor=""#E4E4E4"" id=""at"">(.|\n)*?</table>");
var mat_mulu = reg_mulu.Match(html);
string mulu = mat_mulu.Groups[].ToString();
2、获取小说正文内容
通过章节a标签中的url地址,查看章节内容。

通过分析,正文内容在<dd id="contents">中。
//获取正文
Regex reg = new Regex(@"<dd id=""contents"">(.|\n)*?</dd>");
MatchCollection mc = reg.Matches(html_z);
var mat = reg.Match(html_z);
string content = mat.Groups[].ToString().Replace("<dd id=\"contents\">", "").Replace("</dd>", "").Replace(" ", "").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[].Value.ToString().Split(',')[]; //获取章节目录
Regex reg_mulu = new Regex(@"<table cellspacing=""1"" cellpadding=""0"" bgcolor=""#E4E4E4"" id=""at"">(.|\n)*?</table>");
var mat_mulu = reg_mulu.Match(html);
string mulu = mat_mulu.Groups[].ToString(); //匹配a标签里面的url
Regex tmpreg = new Regex("<a[^>]+?href=\"([^\"]+)\"[^>]*>([^<]+)</a>", RegexOptions.Compiled);
MatchCollection sMC = tmpreg.Matches(mulu);
if (sMC.Count != )
{
//循环目录url,获取正文内容
for (int i = ; 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[].Value; //获取文章内容
string html_z = cra.HttpGet(sMC[i].Groups[].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 id=""contents"">(.|\n)*?</dd>");
MatchCollection mc = reg.Matches(html_z);
var mat = reg.Match(html_z);
string content = mat.Groups[].ToString().Replace("<dd id=\"contents\">", "").Replace("</dd>", "").Replace(" ", "").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();
}
} //Post
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;
} //Get
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、最后效果

4、补充
wlong 同学提了个建议,说用NSoup解析html更方便,我就去查了查,目前没有太大的感触,可能不太会用。DLL下载地址http://nsoup.codeplex.com/
NSoup版:
NSoup.Nodes.Document doc = NSoup.NSoupClient.Parse(html);
//获取小说名字
//<meta name="keywords" content="无疆,无疆最新章节,无疆全文阅读"/>
//获取meta
NSoup.Select.Elements ele = doc.GetElementsByTag("meta");
string name = "";
foreach (var i in ele)
{
if (i.Attr("name") == "keywords")
{
name = i.Attr("content").ToString();
}
}
//获取章节
NSoup.Select.Elements eleChapter = doc.GetElementsByTag("table");//查找table,获取table里的html
NSoup.Nodes.Document docChild = NSoup.NSoupClient.Parse(eleChapter.ToString());
NSoup.Select.Elements eleChild = docChild.GetElementsByTag("a");//查找a标签
//循环目录,获取正文内容
foreach (var j in eleChild)
{
string title = j.Text();//获取章节标题 string htmlChild = cra.HttpGet(j.Attr("href").ToString(), "");//获取文章内容
}
HtmlAgilityPack版(NaYoung提供):
DLL下载地址:HtmlAgilityPack.1.4.6.zip
HtmlWeb htmlWeb = new HtmlWeb();
HtmlDocument document = htmlWeb.Load("http://www.23us.so/files/article/html/13/13694/index.html");
HtmlNodeCollection nodeCollection = document.DocumentNode.SelectNodes(@"//table/tr/td/a[@href]"); //代表获取所有
string name = document.DocumentNode.SelectNodes(@"//meta[@name='keywords']")[].GetAttributeValue("content", "").Split(',')[];
foreach (var node in nodeCollection)
{
HtmlAttribute attribute = node.Attributes["href"];
String val = attribute.Value; //章节url
var title = htmlWeb.Load(val).DocumentNode.SelectNodes(@"//h1")[].InnerText; //文章标题
var doc = htmlWeb.Load(val).DocumentNode.SelectNodes(@"//dd[@id='contents']");
var content = doc[].InnerHtml.Replace(" ", "").Replace("<br>", "\r\n"); //文章内容
//txt文本输出
string path = AppDomain.CurrentDomain.BaseDirectory.Replace("\\", "/") + "Txt/";
Novel(title + "\r\n" + content, name, path);
}
Jumony版:
C# 爬虫 抓取小说的更多相关文章
- Python 爬虫-抓取小说《盗墓笔记-怒海潜沙》
最近想看盗墓笔记,看了一下网页代码,竟然不是js防爬虫,那就用简单的代码爬下了一节: """ 爬取盗墓笔记小说-七星鲁王宫 """ from ...
- Python 爬虫-抓取小说《鬼吹灯之精绝古城》
想看小说<鬼吹灯之精绝古城>,可是网页版的好多广告,还要一页一页的翻,还无法复制,于是写了个小爬虫,保存到word里慢慢看. 代码如下: """ 爬取< ...
- C# 爬虫 正则、NSoup、HtmlAgilityPack、Jumony四种方式抓取小说
心血来潮,想爬点小说.通过百度选择了个小说网站,随便找了一本小说http://www.23us.so/files/article/html/13/13655/index.html. 1.分析html规 ...
- 笔趣看小说Python3爬虫抓取
笔趣看小说Python3爬虫抓取 获取HTML信息 解析HTML信息 整合代码 获取HTML信息 # -*- coding:UTF-8 -*- import requests if __name__ ...
- 爬虫技术 -- 进阶学习(七)简单爬虫抓取示例(附c#代码)
这是我的第一个爬虫代码...算是一份测试版的代码.大牛大神别喷... 通过给定一个初始的地址startPiont然后对网页进行捕捉,然后通过正则表达式对网址进行匹配. List<string&g ...
- Node.js爬虫抓取数据 -- HTML 实体编码处理办法
cheerio DOM化并解析的时候 1.假如使用了 .text()方法,则一般不会有html实体编码的问题出现 2.如果使用了 .html()方法,则很多情况下(多数是非英文的时候)都会出现,这时, ...
- python 爬虫抓取心得
quanwei9958 转自 python 爬虫抓取心得分享 urllib.quote('要编码的字符串') 如果你要在url请求里面放入中文,对相应的中文进行编码的话,可以用: urllib.quo ...
- 爬虫技术(四)-- 简单爬虫抓取示例(附c#代码)
这是我的第一个爬虫代码...算是一份测试版的代码.大牛大神别喷... 通过给定一个初始的地址startPiont然后对网页进行捕捉,然后通过正则表达式对网址进行匹配. List<string&g ...
- 如何利用Python网络爬虫抓取微信朋友圈的动态(上)
今天小编给大家分享一下如何利用Python网络爬虫抓取微信朋友圈的动态信息,实际上如果单独的去爬取朋友圈的话,难度会非常大,因为微信没有提供向网易云音乐这样的API接口,所以很容易找不到门.不过不要慌 ...
随机推荐
- Web Service--第一次接触web service
Web Service 首发于开源中国 1. 背景 中国移动短信网关需求,要能够发送短信.开发材料只有一个短信发送配置:包括ID,password,code,url.一个jar包还有一个老旧的html ...
- java服务端和用户端
1.server Logintherad: package com.zdsofe.server; import java.io.InputStream; import java.io.OutputSt ...
- php的laravel框架使用心得
最近在做一项目,是基于laravel的后台api,用于与手机交互的,数据采用json格式.下面说下怎样在两周内把一个新框架或者语言用的得心应手. 项目采用laravel5.4+dingoapi+jwt ...
- 《Unity3D-播放被打中的时候粒子的特效的代码》
//思路:首先我们需要给这个敌人身上放置上被打中的时候的粒子效果的组件,然后在获取和初始化这个组件然后在播放这个组件.虽然这个过程很简单但是我们要让 组件随着敌人的移动的时候随时触发就必须将这个组件的 ...
- iOS多款源码分享
iOS精选源码 列表联动,Linkage 电商商品详情 AxcUIKit-控件整合框架,快速简单的使用高级控件 GKNavigationBarViewController-导航栏联动 仿京东的加入购物 ...
- grunt+bower依赖管理
安装bower(必须安装git) npm install bower -g bower按照插件命令 初始化配置 bower init 生成bower.json //如果有bower.json 直接输入 ...
- 安装nginx+ngx_lua支持WAF防护功能
安装nginx+ngx_lua支持WAF防护功能 nginx lua模块淘宝开发的nginx第三方模块,它能将lua语言嵌入到nginx配置中,从而使用lua就极大增强了nginx的能力.nginx以 ...
- android项目数据库升级跨版本管理解决方案
目前公司android项目普遍使用框架对数据库进行操作,数据库表与数据实体都具有严格的对应的关系,但是数据库的升依赖不同版本间的升级脚本,如果应用跨多版本进行升级时,当缺失部分升级脚本时就会导致应用异 ...
- netstat命令---输出网络相关的信息
简介 Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Member ...
- 放开那个UI 妹子,让我来(上)
一.前言 今天要学习的内容:今天主要是稍微总结一下,页面中如何用字体代替图片,省事,省时,方便,实用! 小苏啰嗦:人都是有惰性的.真的.刚开始我们有一个经验丰富的美工,加上我们关系又非常好,以至于每次 ...