3
21
2014
0

[C#]利用正则表达式获取网页数据

最近两天处于课程需要,打算从网上收集一些感兴趣的数据。由于最近大家对于环境问题越发重视,于是打算将国内各城市每天的空气质量日报数据收集起来。登录环保部网站之后,果然以表格的形式提供在了网站上。但是没有提供数据导出或者打包下载这些功能。于是又在网上搜索从网页获取数据的方法。其中,不少人都提到和推荐抓取网页源代码,然后用正则表达式进行获取的方法。于是又先对正则表达式进行了一番了解,然后又一番折腾,总算完成了任务。

 

正则表达式(Regular Expression, regex/regexp/re)是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。(本段来源:http://zh.wikipedia.org/wiki/正则表达式

推荐这个网站用来学习正则表达式的使用。感觉稍微看看这个网站,很快就可以上手了。

CSDN上ID为sysdzw的版主多年前写了一个叫做RegTop的命令行小程序(还有个后续的窗体化版本RegTestTool),结合批处理命令可以实现抓取网页数据,可惜本人不灵通,有个关于网页编码的参数总是设置不对(智商拙计-_-|||),只好放弃治疗了……不过RegTestTool这个小工具不妨手头留一个,对于检验正则表达式写的是否正确比较实用。

更多关于正则表达式的内容,这里就不过多展开了,我只看了要用到的部分,言多必失,嘿嘿。下面简单说下C#中正则表达式的用法:

using System.Text.RegularExpression;

string pattern = @"<td.*>(\d{1,8})</td>\n.*<td.*>([^x00-xff]{2,8})</td>\n.*<td.*>(\d{4}-\d\d-\d\d)</td>\n.*<td.*>(\d{1,4})</td>\n.*<td.*>([^x00-xff]{2,6}|--)</td>\n.*<td.*>(.*?)</td>\n.*<td.*>([^x00-xff]{1,4})</td>";

Regex regex = new Regex(pattern);
Match m = regex.Match(web_source);

while (m.Success)
{               
    // Do something... 
    m = m.NextMatch();
}

首先,使用字符串定义正则表达式,由于表达式中少不了各种可能形成的转义字符,所以直接用@""形式表示字符串就OK了。然后,新建一个Regex变量,使用刚才的表达式进行初始化。接着,定义一个Match,就可以接收Regex变量Match(string)方法的结果了。如果匹配成功(m.Success==true),那么匹配结果存储在m.Groups[i]中。值得注意的是,Groups[0]中放的不是正则表达式中第一个匹配项,而是该正则表达式匹配的整个字符串(这里注意下一个正则表达式中可能同时匹配几处),所以使用的时候直接从Group[1]开始。处理完这个匹配之后,使用m.NextMatch()访问下一匹配。哦,最后提一下,使用正则表达式需要System.Text.RegularExpressions命名空间。

 

至于获取网页源代码部分,C#提供了相应的方法(这么快就忘了,唉-_-|||),可惜使用的时候总是无法获得完整的网页源代码。时间关系,没有深究,从网上找到另外一个获得源码的方法:

using System.Net;
/// <summary>
/// 获得网页源代码
/// </summary>
/// <param name="http">页面网址</param>
/// <returns>以字符串形式保存的网页源代码</returns>
private static string GetWebSource(string http)
{
     // Set http web address
     System.Uri url = new System.Uri(http);      
            
     // Set Web Request
     HttpWebRequest hwrq = WebRequest.Create(url) as HttpWebRequest;
     hwrq.Method = "GET";    // (GET/POST)
     hwrq.Referer = http;
     hwrq.Timeout = 50000;   // Timeout(ms)
     hwrq.Accept = "*/*";    // All Types
     hwrq.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)";
     hwrq.CookieContainer = new CookieContainer();   // Cookies

     // Create HttpWebResponse Object
     HttpWebResponse resp = hwrq.GetResponse() as HttpWebResponse;
     StreamReader reader = new StreamReader(
                resp.GetResponseStream(),
                System.Text.Encoding.GetEncoding("UTF-8"));
     string respHTML = reader.ReadToEnd();
            
     resp.Close();
     Console.WriteLine("Web Responsed!");

     return respHTML;
}

对于速度慢的网络或者国外的网站,Timeout可以设置的大一些,不然超时的话就直接报告异常了。

两个主要部分的问题解决了,剩下的工作就简单了:首先抓回来网页源码,然后用正则表达式匹配有用项,再用StringBuilder连接,用StreamWriter写入文件,OK~嘿嘿,收集数据去咯~

Category: C++/C# | Tags: 正则表达式 RegEx 网页源代码 c# | Read Count: 2702

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com