老蜗牛写采集:获取数据(正则篇)

致歉

     首先感谢博友对这个系列的支持,很多加群的人都问我啥时候更新,我一直回答尽快,结果一拖就一年了。因为工作和生活占据我大量的时间,所以只能跟大伙说声抱歉。

使用正则获取数据

  前两篇讲到如何采集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编写正则代码,得到:

<articlesclass="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, @"<articlesclass=""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

原文地址:https://www.cnblogs.com/weitaoxiaozhu/p/7512579.html