忘了什么时候加的,iPad上的人人视频追剧了《我的天才女友》,没事的时候看了下,感觉还不错,进一步了解到原著那不勒斯四部曲,感觉视频进度有些慢,就想找找书看看,一时没找到【PS:购买实体书四十多块钱,虽然目前买得起,但是只是看看故事而不是收藏,不值得买,希望以后有机会补票,而且更习惯使用sp4看pdf或者多看多设备同步阅读进度】,不过找到了在线观看的网站,正好这一段时间有使用C#,就想着使用C#自动将内容抓取下来。断断续续的大概五六个小时的时间,终于功能上实现了。

  由于没怎么研究过爬虫相关知识,不知道是否符合爬虫设计与实践的一些原则,自己做所的不过是通过webrequest抓取页面内容,然后人工分析寻找特征点,找到自己想要的内容。针对这次的任务首先通过目录抓取所有的章节以及对应的页面链接,然后分别抓取每个页面的内容,将章节和内容保存起来。目录中章节链接的提取和每个页面的内容提取都是通过观察尝试实验得到的,不知道是自己哪里设计出了问题,或者就是爬虫本身的特点,感觉很难写出通用的爬虫,很难得到通用的特征点,即使都是在线阅读站点,前端代码不一样,提取的特征都不一样,当前我是直接获取页面内容进行分析,也许会有一些成熟的库,可以直接提取所要的内容。

  不管怎么说,折腾了一场,记录下来,以便以后需要的时候可以查看,而且存储在网络上可以防止丢失。

获取页面内容code:

       /*
* 2019年1月25日09:04:14
* 输入网址,输出网址内容
* NOTE:
* 针对项目进行的特定开发,非通用,编码采取目标网址编码,目前选择GB2312
*/
public string GetContent(string url)
{
string rStr = "";
System.Net.WebRequest req = null;
System.Net.WebResponse resp = null;
System.IO.StreamReader iosr = null;
try
{
req = System.Net.WebRequest.Create(url);
resp = req.GetResponse();
iosr = new System.IO.StreamReader(resp.GetResponseStream(), Encoding.GetEncoding("gb2312"));
rStr = iosr.ReadToEnd();
//Console.WriteLine(rStr);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
return rStr; }

从目录页获得每个章节的名称以及链接

其中获得目标内容的起止标志zhangjie2 /ul就是通过观察实验得到的,目前采用的这种方法比较原始,分析页面内容,不同页面可能都不一样,不知道目前有没有成熟的框架可以方便迅捷的实现目的。

//从初始连接中获得每一个章节名称以及对应的链接。
List<KeyValuePair<string,string>>ParserContentToGetChapters(string str)
{
bool StartFlag=false;
string StartStr = "zhangjie2";
string Endstr = @"/ul";
// 章节 链接
List<KeyValuePair<string,string>>characters = new List<KeyValuePair<string,string>>();
Lexer lexer = new Lexer(str);
INode node = lexer.NextNode();
while(node!=null)
{
string local = node.GetText();
if(local.Contains(StartStr))
{
StartFlag = true;
}
if(local.Contains(Endstr))
{
StartFlag = false;
}
if(StartFlag)
{
if(local.Contains("href"))
{
List<string> tmp = this.GetHerfAndTitle(local);
characters.Add(new KeyValuePair<string, string>(tmp[],tmp[]));
} }
node = lexer.NextNode();
}
return characters;
}
 List<string> GetHerfAndTitle(string input)
{
List<string> ret = new List<string>();
string[] strs = input.Split('"');
int stageflag = ;
foreach(string str in strs)
{
if(str.Contains("a href="))
{
stageflag = ;
continue;
}
else if(str.Contains("title="))
{
stageflag = ;
continue;
}
if(stageflag==)
{
continue;
}
else if(stageflag==)
{
ret.Add(websit + str);
}
else if(stageflag==)
{
ret.Add(str);
break;
}
else
{
break;
} } return ret; }

获得每个章节内容:

     KeyValuePair<string,string> GetSinglePage(string Name,string url)
{
KeyValuePair<string, string> ret = new KeyValuePair<string, string>();
string content = "";
string tmp = this.GetContent(url);
content = this.SinglePageContent(tmp);
ret = new KeyValuePair<string, string>(Name, content);
return ret;
} //从单个页面中找出所有的内容
string SinglePageContent(string all)
{
string ret = "";
bool StartFlag = false;
string StartStr = "div id=\"onearcxsbd\" class=\"onearcxsbd\"";
string Endstr = @"分页";
// 章节 链接
List<KeyValuePair<string, string>> characters = new List<KeyValuePair<string, string>>();
Lexer lexer = new Lexer(all);
INode node = lexer.NextNode();
while (node != null)
{
string local = node.GetText();
if (local.Contains(StartStr))
{
Console.WriteLine("start");
StartFlag = true;
node = lexer.NextNode();
continue;
}
else if(local == Endstr)
{
Console.WriteLine("end");
StartFlag = false;
}
if (StartFlag)
{
if(local == "br /")
{ }
else
{
ret += local;
}
}
node = lexer.NextNode();
} ret = this.DealString(ret);
Console.WriteLine(ret);
return ret;
} //将一些html中的转义字符恢复
string DealString(string input)
{
string ret = input;
Dictionary<string, string> localdict = new Dictionary<string, string>();
localdict.Add("&middot;", "·");
localdict.Add("&ldquo;", "“");
localdict.Add("&rdquo;", "”");
localdict.Add("&mdash;", "—"); foreach (var tmp in localdict)
{
ret = ret.Replace(tmp.Key, tmp.Value);
}
return ret;
}

其他:

1.编码问题,后面需要能够自动获取页面所使用的编码,当初因为使用简繁体操作系统的缘故,浪费了不少时间;

2.最开始考虑使用Dictionary,不过Dictionary对顺序无法保证,改用List<KeyValuePair<string,string>>,防止章节顺序错乱;

3.统一汇总读写还是单条逐个读写,各有利弊,最终采取单个章节单独读写,同时有对内容进行汇总;

4.直接得到的html页面内容中,有些转义字符需要恢复本来的字符,比如&middot; 转换为 · 等。

C#爬虫实践的更多相关文章

  1. 爬虫实践——数据存储到Excel中

    在进行爬虫实践时,我已经爬取到了我需要的信息,那么最后一个问题就是如何把我所爬到的数据存储到Excel中去,这是我没有学习过的知识. 如何解决这个问题,我选择先百度查找如何解决这个问题. 百度查到的方 ...

  2. PHP网络爬虫实践:抓取百度搜索结果,并分析数据结构

    百度的搜索引擎有反爬虫机制,我先直接用guzzle试试水.代码如下: <?php /** * Created by Benjiemin * Date: 2020/3/5 * Time: 14:5 ...

  3. JAVA爬虫实践(实践一:知乎)

    爬虫顺序 1.分析网站网络请求 通过浏览器F12开发者工具查看网站的内容获取方式. 2.模拟HTTP请求,获取网页内容. 可以采用HttpClient,利用JAVA HttpClient工具可以模拟H ...

  4. python爬虫实践(二)——爬取张艺谋导演的电影《影》的豆瓣影评并进行简单分析

    学了爬虫之后,都只是爬取一些简单的小页面,觉得没意思,所以我现在准备爬取一下豆瓣上张艺谋导演的“影”的短评,存入数据库,并进行简单的分析和数据可视化,因为用到的只是比较多,所以写一篇博客当做笔记. 第 ...

  5. python爬虫实践(一)

    最近在学习爬虫,学完后想实践一下,所以现在准备爬取校花网的一部分图片 第一步,导入需要的库 from urllib import request #用于处理request请求和获得响应 from ur ...

  6. 零python基础--爬虫实践总结

    网络爬虫,是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本. 爬虫主要应对的问题:1.http请求 2.解析html源码 3.应对反爬机制. 觉得爬虫挺有意思的,恰好看到知乎有人分享的一个爬虫 ...

  7. Python 3 Anaconda 下爬虫学习与爬虫实践 (1)

    环境python 3 anaconda pip 以及各种库 1.requests库的使用 主要是如何获得一个网页信息 重点是 r=requests.get("https://www.goog ...

  8. 基于nightmare的美团美食商家爬虫实践

    前言美团商家页分析需要爬取的数据有(这里没有按人数爬)爬虫工具选取pysipderscrapynightmare同步任务js动态加载中断继续爬坑总结示例代码 前言 上学的时候自己写过一些爬虫代码,比较 ...

  9. 爬虫实践--CBA历年比赛数据

    闲来无聊,刚好有个朋友来问爬虫的事情,说起来了CBA这两年的比赛数据,做个分析,再来个大数据啥的.来了兴趣,果然搞起来,下面分享一下爬虫的思路. 1.选取数据源 这里我并不懂CBA,数据源选的是国内某 ...

随机推荐

  1. 重启部署在Linux系统下的tomcat服务

    重启部署在Linux系统下的tomcat服务具体的操作步骤: 1.在Winscp上建立连接,输入用户和密码,这个密码一般是看不到的: 2.查看服务:ps -ef  |  gerp  Java  注意在 ...

  2. ASP.NET WebForm 之 Ajax 请求后端处理

    概述 ASP.NET MVC中的异步用途非常广泛,操作起来也非常简单.前台请求异步请求 Controller下的Action 方法,后端返回ActionResult 即可.但是在ASP.NET Web ...

  3. [转].Net Core上用于代替System.Drawing的类库

    本文转自:http://www.tuicool.com/wx/iuaINjy 目前.Net Core上没有System.Drawing这个类库,想要在.Net Core上处理图片得另辟蹊径. 微软给出 ...

  4. NET平台4.0 发布网站流程及出错总结

    1.进入IIS设置,在控制面板中选择“管理工具”,进入后选择 “Internet 信息服务(IIS)管理器” 2.点击[添加]应用程序池,根据版本选择framework 3.添加网站 ,右击网站,添加 ...

  5. Object公用方法

    Object是所有类的父类,任何类都默认继承Object. Object类到底实现了哪些方法?   1.clone方法 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否 ...

  6. hdu 4276 树形m时间1进n出

    http://acm.hdu.edu.cn/showproblem.php?pid=4276 一般题目是求回到原地,而这道题规定从1进n出.所以1-n这条路是必走,其他走不走无所谓. 这样很自然通过d ...

  7. UITableView分隔线

    问题1: 在ios中使用UITableView时,当行数较少是,可能一屏幕能显示完全所有行,这时候会出现下面的问题,显示多余的分隔线 图如下: 解决方案: //解决方案1 //添加如下代码 -(CGF ...

  8. C++ VS编译问题--LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    用VS编译时,当出现错误LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏: 这个问题的解决方案为: 1. 找到项目\xx属性\配置属性\清单工具\输 ...

  9. u-boot分析(四)---设置异常向量表|设置SVC模式

    u-boot分析(四) 通过前三篇的分析,我们对u-boot已经有了整体的认识和掌握,但是我们仍然对于其部分硬件是如何初始化的不太清楚,所以接下来几篇博文我将会对我们在http://www.cnblo ...

  10. 二种方法安装卸载Windows服务的命令

    第一种方法:通过Dos命令安装系统服务1. 开始 运行输入 cmd 进入dos窗口2. cd命令进入到C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727目录下, ...