最近两天处于课程需要,打算从网上收集一些感兴趣的数据。由于最近大家对于环境问题越发重视,于是打算将国内各城市每天的空气质量日报数据收集起来。登录环保部网站之后,果然以表格的形式提供在了网站上。但是没有提供数据导出或者打包下载这些功能。于是又在网上搜索从网页获取数据的方法。其中,不少人都提到和推荐抓取网页源代码,然后用正则表达式进行获取的方法。于是又先对正则表达式进行了一番了解,然后又一番折腾,总算完成了任务。
正则表达式(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~嘿嘿,收集数据去咯~
2021年4月25日 18:31
敬启者:个人小网站希望大家多多支持 感谢您对我们热心的支持 f88tw┃华歌尔┃I appreciate your kind assistance. f88tw| 粗工| 粗工内容 | 粗工| 粗工内容 |墓园|捡骨流程|捡骨费用|捡骨时间|禁忌|捡骨颜色|捡骨师|新竹|时间|台北|桃园|苗栗|头份|https://mypaper.m.pchome.com.tw/f88tw