老蜗牛写采集:获取数据(正则篇)
来源:互联网 发布:linq 不重复数据 编辑:程序博客网 时间:2024/05/18 03:24
致歉
首先感谢博友对这个系列的支持,很多加群的人都问我啥时候更新,我一直回答尽快,结果一拖就一年了。因为工作和生活占据我大量的时间,所以只能跟大伙说声抱歉。
使用正则获取数据
前两篇讲到如何采集html数据,那采集回来肯定要截取我们有用的部分,举个例子。我们要采集搜狐新闻的社会栏目,地址如下:
http://news.sohu.com/shehuixinwen.shtml
我们首先获取到新闻列表,看上两章介绍到使用xNet获取到搜狐新闻的社会栏目的html源码,当然你可以使用httprequest或者第三方组件。代码如下:
var html = string.Empty; using (var request = new xNet.HttpRequest()) { html = request.Get("http://news.sohu.com/shehuixinwen.shtml").ToString(); }
得到html值:
<!doctype html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/ xhtml1-transitional.dtd"><script type="text/javascript"> var pvinsight_page_ancestors = '143746642;143746651';</script><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="content-type" content="text/html; charset=gb2312" /><title>社会新闻-搜狐新闻</title><script type="text/javascript" src="http://www.sohu.com/sohuflash_1.js"></script><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /><meta name="description" content="搜狐社会新闻关注社会民生、百姓问题。精品栏目:社会万象、百姓生活" /><meta name="keywords" content="社会,社会新闻,万象,百姓,口述" /><meta name="robots" content="all" /><link type="text/css" rel="stylesheet" href="http://css.sohu.com/upload/global1.4.1.css" /><link rel="stylesheet" href="http://news.sohu.com/upload/zhengyufeng/xinwenerjiye/style1.css" /><script type="text/javascript" src="http://js.sohu.com/library/jquery-1.7.1.min.js"></script><script type="text/javascript" src="http://news.sohu.com/upload/2013page/j.js"></script><!--[if IE 6]> <script src="http://news.sohu.com/upload/zhengyufeng/pngAlaph.js"></script> <script>DD_belatedPNG.fix('#header,h3,h3 span,.shipin,.dashiye_list li,.liushengji_list li,#imgText b,img,.followScroll a,#contentA .left .tit span'); </script><![endif]-->.....<script language="javascript">if(_wratingId !=null){document.write('<scr'+'ipt type="text/javascript">');document.write('var vjAcc="'+_wratingId+'";');document.write('var wrUrl="http://sohu.wrating.com/";');document.write('try{vjTrack();}catch(e){}');document.write('</scr'+'ipt>');}</script><script> require(["sjs/matrix/ad/passion"]);</script><!--SOHU:SUB_FOOT_DIV--> </body></html>
因为html比较大,所以不显示全部,为了防止搜狐改版,我还是截取一段样板
<div class="article-list"><div class="article"> <h3><span class="com-num"><a target="_blank" href="#">comment num</a></span><a target="_blank" href="http://www.sohu.com/a/190778382_119562">“五假副部”现形始末:被指讲话稿都念不顺</a></h3> <p>...<a target="_blank" href="http://www.sohu.com/a/190778382_119562">阅读全文>></a></p></div><div class="pic-group"></div><div class="fun clear"> <div class="share"> <ul> <li class="s-t">分享到 |</li> <li class="blg"><a title="·??í?????ü????" href="javascript:void(0)"></a></li> <li class="qq"><a title="·??í??QQ????" href="javascript:void(0)"></a></li> <li class="rrw"><a title="·??í????????" href="javascript:void(0)"></a></li> <li class="db"><a title="·??í????°ê" href="javascript:void(0)"></a></li> <li class="itb"><a title="·??í??i?ù°?" href="javascript:void(0)"></a></li> </ul> </div><!--<div class="label">±ê????<a target="_blank" href="#">??????</a> <a target="_blank" href="#">???ú</a> <a target="_blank" href="#">????</a></div> --><div class="time"> 发表于 2017-09-09 13:03</div></div></div>
那我们要获取新闻列表的标题和连接地址怎么获取了? 那么就要介绍本篇的核心,使用正则,一讲到正则很多人会觉得很难,因为写法比较火星语。第二就是测试正则,市面上有很多测试工具,包括在线的都有,看你的喜好了,这里我要介绍一个超级无敌好用的测试工具,大家可以去网上下载或者在本文最后的会有下载链接,这个工具名叫:RegExBuilder 为啥说他好用,主要是他采用即时匹配,这样对新手可以一步步的调试编写正则。使用上面的工具可以得到以下正则匹配新闻列表和连接地址代码:
<h3>[^>]*>[^>]*>[^>]*>[^>]*><a.target="_blank"\shref="(?<url>[^"]*)[^>]*>(?<title>[^<]*)
写得比较粗犷,估计一百个人有一百个写法,所以这也是正则有魔力的地方,入门难,入门后小菜一碟。这里要说明一下,(?<title>[^<]*)是可以通过 title 这个关键字获取值,后面代码会写到。但在javascript、java、php等是按索引获取的,所以C#还是比较人性化滴
使用代码获取我们要的数据,首先得定义一个新闻类:
class NewsItem { public string Title { get; set; } public string Url { get; set; } public string Content { get; set; } }
逻辑代码
var html = string.Empty; using (var request = new xNet.HttpRequest()) { html = request.Get("http://news.sohu.com/shehuixinwen.shtml").ToString(); } var newsList = new List<NewsItem>(); var mc = Regex.Matches(html, @"<h3>[^>]*>[^>]*>[^>]*>[^>]*><a.target=""_blank""\shref=""(?<url>[^""]*)[^>]*>(?<title>[^<]*)"); foreach (Match m in mc) { var newsItem = new NewsItem(); newsItem.Title = m.Groups["title"].Value; newsItem.Url= m.Groups["url"].Value; //按索引获取,具体看RegExBuilder工具的索引 newsItem.Url = m.Groups[1].Value; newsItem.Title = m.Groups[2].Value;
newsList.Add(newsItem); }
注意转译字符串哦,不是两个正则不一样,然后就可以得到整个新闻的列表,有人会提问,那下一页呢?嘿嘿...车只能开到这了。
获取新闻内容,拿到地址后,可以用xNet获取html源码,然后分析,示例如下:
先用RegExBuilder编写正则代码,得到:
<article\sclass="article">(?<content>.+?)</article>
这里要勾选Singleline选项,Singleline顾名思义就是全部按单行匹配,就是有换行也按单行,还有其他几种匹配模式,其实都可以按字面意思去理解。譬如:
IgnoreCase:忽略大小写
Multiline:多行匹配
RightToLeft:从右到左匹配
其他可以参考这位道友的文章,http://blog.csdn.net/qq_33729889/article/details/63035440
获取数据的逻辑代码
foreach (var newItem in newsList) { using (var request = new xNet.HttpRequest()) { html = request.Get(newItem.Url).ToString(); } Match m = Regex.Match(html, @"<article\sclass=""article"">(?<content>.+?)</article>", RegexOptions.Singleline); if (m.Success) { newItem.Content = m.Groups["content"].Value; } }
以上就是简单使用正则获取html数据的案例。
一些简单正则的使用
其实会使用一些简单的东西基本上就能满足我们的开发需求
譬如:<div>数据</div>
最简单的写法:<div>(\w+)</div> 括号是你要取的数据\w是匹配所有的字符,+是代表一个以上,如果使用*就是包含零个字符
进阶一点的写法:<[^>]*>(\w+)</div> [^>]*是如果非>则一直匹配
更多的正则教程可以参考http://www.cnblogs.com/zery/p/3438845.html
附上正则匹配小工具下载地址:
http://www.jb51.net/softs/389196.html
C#.NET开源项目、机器学习、足球赛事资料库
开源Q群:302961959
足球研究技术群:142780296
- 老蜗牛写采集:获取数据(正则篇)
- 老蜗牛写采集:获取数据(正则篇)
- php正则与数据采集
- 正则采集
- python从零写一个采集器:获取网页源码
- python从零写一个采集器:获取网页信息
- 动画程序编写——DirectDraw之旅(1)(异域の蜗牛注:老文章回顾)
- 动画程序编写——DirectDraw之旅(2)(异域の蜗牛注:老文章回顾)
- 动画程序编写——DirectDraw之旅(3)(异域の蜗牛注:老文章回顾)
- HTTP协议、正则表达式、HTML,WEB数据采集基础
- Java进行HTML数据采集:浅谈强大的group正则
- Python网络数据采集——正则表达式
- ftp数据采集的代码(一次性数据采集)
- 蜗牛历险记(开篇)
- 蜗牛
- 蜗牛
- 蜗牛
- 蜗牛
- 测试信息
- Python 错误和异常
- string类的引用计数的写时拷贝分析
- BZOJ2982: combination(Lucas定理)
- [Suzuki85]轮廓跟踪算法论文翻译
- 老蜗牛写采集:获取数据(正则篇)
- jdk1.7环境java代码访问https(connection reset)
- 如何判定对象已死可以回收内存
- book1 unit5 after-class reading 1 : Animal Play
- windows下超简单安装Anaconda配置环境,并在pycharm中运行安装TensorFlow
- 【笔记篇】莫队算法(二)
- sparksteaming---实时流计算Spark Streaming原理介绍
- .两个对象值相(x.equals(y)==true),但却可有不同的hash code,这句话对不对?
- LightOJ