因为懒人太多,造成现在网页数据采集非常的流行,我也来写个简单的记录一下。

之前写了MVC的基本框架的搭建随笔,后面因为公司太忙,个人感情问题:(,导致不想写了,就写了两篇给删除了,现在就搁浅了,

本人是马鞍山人,喜欢看看老家的招聘信息,看看我有没有机会回家发展,回家找妹子:),这是马鞍山的招聘网站 http://www.masrc.com.cn/

因他的一些信息只显示单位不显示具体的招聘职位,所以我闲着蛋疼,我就想做一个采集站,将数据采集出来,好方便浏览..

下面就是显示的页面,对我这个写代码的来说,根本找不到关于我的职位呀,一个一个的点多累啊,而且他的搜索有点问题,总搜索不出我要的....

看他的HTML代码:

基本都table加A标签的组合,家乡的网站,我就不吐槽了....

注意他的链接格式记录一下: <a class="black_9" href="*"><font>*</font></a>

开始写代码吧...

我用的是VS2012 + ASP.NET MVC4,请忽略这些细节....

因为不需要默认的样式,所以选择一个空的ASP.NET MVC项目

下面是目录结构

新建一个HomeControllers并建立一个基础Action  Index  (mvc基础就不讲了,重点是采集对吧)

接下来,根据上面分析的链接方式<a class="black_9" href="*"><font>*</font></a>

写一段采集需要的正则表达式

            string htmlregstr = @"(?is)<a[^>]*?href=(['""]?)(?<url>[^'""\s>]+)?[^>]*><font[^>]*>(?<text>(?:(?!</?a\b).)*)</font></a>";//分组

这段正则表达式将我需要的信息作了分组,比如说href的指向链接url 和a标签的text文本  <font>在我需要的链接都有,所以需要去掉

现在初步的思路是将web页面的当中的a标签通过这个正则全部取出

先查看该网站文本的编码方式,在获取文本流时需要

如图,该网站用的gb2312的编码方式

下面是采集的代码有注释:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc; namespace YanNis.WebSite.Collect.MasRC.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
//a标签的正则
string htmlregstr = @"(?is)<a[^>]*?href=(['""]?)(?<url>[^'""\s>]+)?[^>]*><font[^>]*>(?<text>(?:(?!</?a\b).)*)</font></a>";//分组 //需要采集的页面地址
string WebLink = "http://www.masrc.com.cn/"; //创建一个请求
WebRequest webReq = System.Net.WebRequest.Create(WebLink); //获取响应
WebResponse webRes = webReq.GetResponse(); //使用GB2312的编码方式 获取响应的文本流
StreamReader sReader = new StreamReader(webRes.GetResponseStream(), System.Text.Encoding.GetEncoding("gb2312")); //将文本读出
string content = sReader.ReadToEnd(); //正则匹配
MatchCollection matchCollecti = Regex.Matches(content, htmlregstr, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline); //创建一个Model用于前台查看
List<WebLink> WebLinks = new List<WebLink>(); //遍历每一个匹配
foreach (Match ma in matchCollecti)
{
//获取重要的信息
string title = ma.Groups["text"].Value;
string link = ma.Groups["url"].Value; //因为需要的链接地址都有showMemberzpDetail.asp 所以用他做为过滤
if (ma.Success && link.IndexOf("showMemberzpDetail") >= )
{
WebLinks.Add(new WebLink
{
Title = title,
Url = link
}); }
}
//返回 MODEL
return View(WebLinks);
} } public class WebLink
{
public WebLink()
{
Desc = new List<WebLink>();
} public string Title { get; set; } public string Url { get; set; } public List<WebLink> Desc { get; set; }
} }

View代码:

@model IEnumerable<YanNis.WebSite.Collect.MasRC.Controllers.WebLink>

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<ul>
@foreach (var m in Model)
{
<li><a href="@m.Url">@m.Title</a></li>
} </ul>
</div>
</body>
</html>

效果如下:

已经获取了,接下来就要去找到链接页面的详细岗位了,如图:

惯例,查看他的链接代码

还是一样 table+a的组合

还是刚刚那个正则,但是没有font这个标签所以稍加改动

        string Detailhtmlregstr = @"(?is)<a[^>]*?href=(['""]?)(?<url>[^'""\s>]+)?[^>]*>(?<text>(?:(?!</?a\b).)*)</a>";

接下来的思路是根据获取指向的链接的页面,将岗位的链接获取在手

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc; namespace YanNis.WebSite.Collect.MasRC.Controllers
{
public class HomeController : Controller
{
string htmlregstr = @"(?is)<a[^>]*?href=(['""]?)(?<url>[^'""\s>]+)?[^>]*><font[^>]*>(?<text>(?:(?!</?a\b).)*)</font></a>"; string Detailhtmlregstr = @"(?is)<a[^>]*?href=(['""]?)(?<url>[^'""\s>]+)?[^>]*>(?<text>(?:(?!</?a\b).)*)</a>"; public ActionResult Index()
{
//a标签的正则 //需要采集的页面地址
string url = "http://www.masrc.com.cn/"; //创建一个请求
WebRequest webReq = System.Net.WebRequest.Create(url); //获取响应
WebResponse webRes = webReq.GetResponse(); //使用GB2312的编码方式 获取响应的文本流
StreamReader sReader = new StreamReader(webRes.GetResponseStream(), System.Text.Encoding.GetEncoding("gb2312")); //将文本读出
string content = sReader.ReadToEnd(); //正则匹配
MatchCollection matchCollecti = Regex.Matches(content, htmlregstr, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline); //创建一个Model用于前台查看
List<WebLink> WebLinks = new List<WebLink>(); //遍历每一个匹配
foreach (Match ma in matchCollecti)
{
//获取重要的信息
string title = ma.Groups["text"].Value;
string link = ma.Groups["url"].Value; //因为需要的链接地址都有showMemberzpDetail.asp 所以用他做为过滤
if (ma.Success && link.IndexOf("showMemberzpDetail") >= )
{
WebLinks.Add(new WebLink
{
Title = title,
Url = url + link,
Desc = GetDetailData(url + link)
}); }
}
//返回 MODEL
return View(WebLinks);
} public List<WebLink> GetDetailData(string url)
{
//创建一个请求
WebRequest webReq = System.Net.WebRequest.Create(url); //获取响应
WebResponse webRes = webReq.GetResponse(); //使用GB2312的编码方式 获取响应的文本流
StreamReader sReader = new StreamReader(webRes.GetResponseStream(), System.Text.Encoding.GetEncoding("gb2312")); //将文本读出
string content = sReader.ReadToEnd(); //正则匹配
MatchCollection matchCollecti = Regex.Matches(content, Detailhtmlregstr, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline); //创建一个Model用于前台查看
List<WebLink> WebLinks = new List<WebLink>(); //遍历每一个匹配
foreach (Match ma in matchCollecti)
{
//获取重要的信息
string title = ma.Groups["text"].Value;
string link = ma.Groups["url"].Value; //因为需要的链接地址都有showMemberzpDetail.asp 所以用他做为过滤
if (ma.Success && link.IndexOf("showPosDetail_new") >= )
{
WebLinks.Add(new WebLink
{
Title = title,
Url = url + link
}); }
} return WebLinks;
} } public class WebLink
{
public WebLink()
{
Desc = new List<WebLink>();
} public string Title { get; set; } public string Url { get; set; } public List<WebLink> Desc { get; set; }
} }

VIEW代码

@model IEnumerable<YanNis.WebSite.Collect.MasRC.Controllers.WebLinks>

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<ul>
@foreach (var m in Model)
{
<li><a href="@m.Url">@m.Title</a>
<ul>
@foreach (var n in m.Desc)
{
<li><a href="@n.Url">@n.Title</a></li>
}
</ul>
</li>
} </ul>
</div>
</body>
</html>

效果:

有没有发现 其实Controller里有很多相同重复的代码,我们可以将其简化,增加可读性,使用递归去获取

简化后的代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc; namespace YanNis.WebSite.Collect.MasRC.Controllers
{
public class HomeController : Controller
{
string urllink = "http://www.masrc.com.cn/"; public ActionResult Index()
{
string htmlregstr = @"(?is)<a[^>]*?href=(['""]?)(?<url>[^'""\s>]+)?[^>]*><font[^>]*>(?<text>(?:(?!</?a\b).)*)</font></a>"; List<WebLinks> WebLinks = GetDetailData("", htmlregstr, "showMemberzpDetail"); //返回 MODEL
return View(WebLinks);
} public List<WebLinks> GetDetailData(string url, string Regstr, string Filterstr)
{
if (url == "")
url = urllink;
//创建一个请求
WebRequest webReq = System.Net.WebRequest.Create(url); //获取响应
WebResponse webRes = webReq.GetResponse(); //使用GB2312的编码方式 获取响应的文本流
StreamReader sReader = new StreamReader(webRes.GetResponseStream(), System.Text.Encoding.GetEncoding("gb2312")); //将文本读出
string content = sReader.ReadToEnd(); //正则匹配
MatchCollection matchCollecti = Regex.Matches(content, Regstr, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline); //创建一个Model用于前台查看
List<WebLinks> WebLinks = new List<WebLinks>(); //没有了<font> 增加一个<td>
string Detailhtmlregstr = @"(?is)<a[^>]*?href=(['""]?)(?<url>[^'""\s>]+)?[^>]*>(?<text>(?:(?!</?a\b).)*)</a>"; //遍历每一个匹配
foreach (Match ma in matchCollecti)
{
//获取重要的信息
string title = ma.Groups["text"].Value;
string link = ma.Groups["url"].Value; //过滤
if (ma.Success && link.IndexOf(Filterstr) >= )
{
WebLinks w = new WebLinks()
{
Title = title,
Url = urllink + link
};
if (Filterstr != "showPosDetail_new")
w.Desc = GetDetailData(w.Url, Detailhtmlregstr, "showPosDetail_new");
WebLinks.Add(w);
}
}
return WebLinks;
} } public class WebLinks
{
public WebLinks()
{
Desc = new List<WebLinks>();
} public string Title { get; set; } public string Url { get; set; } public List<WebLinks> Desc { get; set; }
} }

很简单吧,采集是多么的简单呀

如何防采集呢,可以学习学习淘宝,之前通过淘宝客链接采集过淘宝的页面,普通办法是无法采集到,只能获取空白的页面,是通过添加修改HEADERS才能获取到,可以借鉴一下。明天就把怎么通过淘宝客的链接获取淘宝宝贝详情页的方法给放出来,我有可能会忘记哦^^

这段代码是作为演示,代码可以继续优化,增加可读性和响应速度,也可改为AJAX异步获取...

简单的网页采集程序(ASP.NET MVC4)的更多相关文章

  1. 简单的java采集程序二

    继[简单的java采集程序],这里将完成对整个网站的号码段的采集任务. [使用预编译+批处理采集网页内容至数据库表中]          在之前我们用statement类来创建sql语句的执行对象,以 ...

  2. 简单java采集程序一

    [目标任务]通过该网站采集全国的手机号码段至数据库表中 [完成过程] 1.初涉正则表达式,学会写简单的正则表达式 2.获取单个网页内容,学会java中基本的IO流 3.将获取数据插入mysql数据库表 ...

  3. 初入码田--ASP.NET MVC4 Web应用之创建一个空白的MVC应用程序

    初入码田--ASP.NET MVC4 Web应用开发之一  实现简单的登录 初入码田--ASP.NET MVC4 Web应用开发之二 实现简单的增删改查 2016-07-29 在此之前,需要一台电脑( ...

  4. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(37)-文章发布系统④-百万级数据和千万级数据简单测试

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(37)-文章发布系统④-百万级数据和千万级数据简单测试 系列目录 我想测试EF在一百万条数据下的显示时间! ...

  5. ASP.NET MVC4简单使用ELMAH记录系统日志

    ASP.NET MVC4简单使用ELMAH记录系统日志 前言 在项目开发.测试以及已经上线的项目中都会存在bug,而如果我们在项目的各个阶段都能及时的监控系统出现的任何问题,那么对于我们开发人员来说完 ...

  6. 初入码田--ASP.NET MVC4 Web应用开发之二 实现简单的增删改查

    初入码田--ASP.NET MVC4 Web应用之创建一个空白的MVC应用程序 初入码田--ASP.NET MVC4 Web应用开发之一 实现简单的登录 2016-07-29  一.创建M002Adm ...

  7. 初入码田--ASP.NET MVC4 Web应用开发之一 实现简单的登录

    初入码田--ASP.NET MVC4 Web应用之创建一个空白的MVC应用程序 初入码田--ASP.NET MVC4 Web应用开发之二 实现简单的增删改查 2016-07-24 一.创建T4模板,建 ...

  8. asp.net mvc4 过滤器的简单应用:登录验证

    直接上代码,不要说话. ASP.NET MVC4过滤器的简单应用:验证登录 [AcceptVerbs(HttpVerbs.Post)] public ActionResult login(FormCo ...

  9. windows server 2012 r2 iis8.5 部署asp.net mvc4/5程序小结

    windows server 2012 r2 iis8.5 部署asp.net mvc4/5程序小结 原文链接:http://www.xuanhun521.com/Blog/66d491f8-b479 ...

随机推荐

  1. POJ 3616 DP

    题意:给你N的时间,M的工作时间段,每个时间段有一个权重,还有一个R,每次完成一个工作需要休息R,问最后在时间N内,最大权重是多少. 思路:很简单的DP,首先对区间的右坐标进行排序,然后直接转移方程就 ...

  2. 启动列表的activity

    每学一个知识点就要重新创建一个项目,感觉那样太繁琐了,特别是android studio开发,没创建一个项目都会重新打开一个窗口 所以我就在那想,何不有一个功能列表,点击每一个列表项的时候就跳转到那个 ...

  3. 【转】C/C++中的日期和时间 TIME_T与STRUCT TM转换——2013-08-25 16

    http://www.cnblogs.com/Wiseman/archive/2005/10/24/260576.html 摘要: 本文从介绍基础概念入手,探讨了在C/C++中对日期和时间操作所用到的 ...

  4. oracle数据库入门

    oracle  数据库入门. 1.数据 2.数据存储的地方:变量 数组 容器 (内存中),文件,数据库(文件) 3.数据库系统:sqlserver 2000   2005  2008  mysql 5 ...

  5. Python入门学习教程:数据库操作,连接MySql数据库

    各位志同道合的同仁可以点击上方关注↑↑↑↑↑↑ 本教程致力于程序员快速掌握Python语言编程. 本文章内容是基于上次课程Python教程:Python教程:连接数据库,对数据进行增删改查操作 和py ...

  6. Magento 中的多个类别的筛选产品集合

    通过在 Magento 中的多个类别的筛选产品集合. 按只 1 类别筛选 Magento 提供筛选器,可以使用直接从该集合的类型: $_category = Mage::getModel('catal ...

  7. ThinkPHP函数详解:A方法

    A方法用于在内部实例化控制器,调用格式:A('[项目://][分组/]模块','控制器层名称')最简单的用法: $User = A('User'); 复制代码 表示实例化当前项目的UserAction ...

  8. 利用php给图片添加文字水印--面向对象与面向过程俩种方法的实现

    1: 面向过程的编写方法 //指定图片路径 $src = '001.png'; //获取图片信息 $info = getimagesize($src); //获取图片扩展名 $type = image ...

  9. eclipse 好用的快捷键

    Ctrl+Shift+X 把当前选中的文本全部变味小写 Ctrl+Shift+Y 把当前选中的文本全部变为小写 Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定) ...

  10. poj1308 Is It A Tree?(并查集)详解

    poj1308   http://poj.org/problem?id=1308 题目大意:输入若干组测试数据,输入 (-1 -1) 时输入结束.每组测试数据以输入(0 0)为结束标志.然后根据所给的 ...