突然要用到地区数据,想到以前用python的Scrapy框架写过一个爬虫,于是打算直接去国家统计局把最新的地区数据抓取回来.本想只需要copy一下以前的代码,就可以得到新鲜出炉的数据,谁知打开以前的项目,脑子一片空白,一点印象都莫得.只恨当时没有做做笔记,写个博客啥的来加深一下影响.点子已经到这里来了,于是在.net core框架下再做了一点简单的爬取工作,并截取前面一部分,整理成文,方便以后回顾
网页分析
网页数据抓取,第一步就是分析网页的结构,包括下面3种基本的信息:
1网页编码格式:得到正确的编码格式是非常重要的,乱码可是会让人头疼
2锁定目标节点:找到目标数据所在的节点
3找寻多级依赖关系:例如本次爬取的省,市,区...,他们之间是存在依赖关系的,找到它们之间的关系才能获取完整的数据
网页的复杂程度不止于此,当遇到复杂的情况时,我们需要分析更多的信息,但就本次抓取而言,上述信息足以,所以不多做考虑
下面就以抓取省份或直辖市为例:
页面如下:
查看页面元信息,页面编码格式为GB2312
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
锁定数据所在的dom节点
1 2 北京市 3 天津市 4 河北省 5 山西省 6 内蒙古自治区 7 辽宁省 8 吉林省 9 黑龙江省10 11 12 上海市13 江苏省14 浙江省15 安徽省16 福建省17 江西省18 山东省19 河南省20 21 22 湖北省23 湖南省24 广东省25 广西壮族自治区26 海南省27 重庆市28 四川省29 贵州省30 31 32 云南省33 西藏自治区34 陕西省35 甘肃省36 青海省37 宁夏回族自治区38 新疆维吾尔自治区39
找寻依赖关系
<a>标签的href属性的数字部分是进入下一级地域的关键
数据抓取
在分析完页面结构后,下一步就可以开始我们的数据抓取
首先安装AngleSharp(Install-Package AngleSharp )的包,
AngleSharp :一个基于.NET(C#)开发的专门为解析xHTML源码的DLL组件(),有了它我们就可以把得到的网页内容转换成规则的DOM,找寻我们的目标节点就变得非常简单
其次我所用的版本net core(2.2)不支持GB2312,如果直接操作,得到的只能是乱码,解决方法如下
1安装System.Text.Encoding.CodePages包(Install-Package System.Text.Encoding.CodePages)
2在启动类Starup的Configure方法中加入Encoding.RegisterProvider(CodePagesEncodingProvider.Instance)
做好上述的工作准备后,具体的代码如下
1 ///2 /// 爬虫辅助类 3 /// 4 public static class SpiderHelper 5 { 6 private static HtmlParser htmlParser = new HtmlParser(); 7 8 public static string GetHtml(string url) 9 {10 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);11 12 HttpWebResponse response = (HttpWebResponse)request.GetResponse();13 14 try15 {16 Stream receive = response.GetResponseStream();17 18 StreamReader readStream = new StreamReader(receive, Encoding.GetEncoding("GB2312"));19 20 return readStream.ReadToEnd();21 }22 23 catch (Exception)24 {25 return "";26 }27 }28 29 ///30 /// 获取省份31 /// 32 private static ListGetProvinces()33 {34 string html = GetHtml("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2018/index.html");35 36 List data = new List ();37 38 if (string.IsNullOrEmpty(html)) return data;39 40 //网页整体dom41 var document = htmlParser.ParseDocument(html);42 43 //目标元素dom,class为provincetr的tr元素下的a标签44 var list = document.QuerySelectorAll("tr.provincetr a");45 46 foreach (var item in list)47 {48 string name = item.TextContent;49 50 string id = item.GetAttribute("href").Replace(".html", "");51 52 data.Add(new AreaViewModel()53 {54 Id = id,55 Name = name,56 ParentId = "",57 Type = 2,58 Zip = ""59 });60 };61 62 return data;63 }64 }
总结
上述的例子属于最基本的类型,对于更多网页数据的爬取,需要考虑的情况更加复杂,那时候就需要更加深入的剖析结构后通过更加复杂的技术来获取数据.但是最基本通用的原理还是和本文介绍的小例子相似
(终)
文档信息
- 发表作者:
- 发表出处:
- 原文地址:
- 版权信息:本作品采用进行许可。
感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮。本文欢迎各位转载,但是转载文章之后必须在文章页面中给出作者和原文连接。