Ioc在重构代码中的应用
最近lz在写抓工商公式系统(http://www.gsxt.gov.cn/index.html)的爬虫,其中的难点就是在怎么过极验验证码,搞的我不要不要的!如下:
简直是各种坑,被搞的死去活来以后还是解决了。现在回到主题!
我们不是要抓工商公式系统的数据吗?所以我们先建两个实体BaseInfo(基本信息)和LegInfo(股东信息)
public partial class BaseInfo { public BaseInfo() { } public BaseInfo(string html) { } #region Model /// <summary> /// /// </summary> public int Id { get; set; } /// <summary> /// 成立日期 /// </summary> public string ApprDate { get; set; } /// <summary> /// 公司全称 /// </summary> public string EntName { get; set; } /// <summary> /// 公司类型 /// </summary> public string EntType { get; set; } /// <summary> /// 住所 /// </summary> public string Dom { get; set; } /// <summary> /// 核准日期 /// </summary> public string EstDate { get; set; } /// <summary> /// 法人 /// </summary> public string Lerep { get; set; } /// <summary> /// 营业期限自 /// </summary> public string OpFrom { get; set; } /// <summary> /// 营业期限至 /// </summary> public string OpTo { get; set; } /// <summary> /// 经营范围 /// </summary> public string OpScope { get; set; } /// <summary> /// 注册号 /// </summary> public string RegNo { get; set; } /// <summary> /// 登记机关 /// </summary> public string RegOrg { get; set; } /// <summary> /// 登记状态 /// </summary> public string RegState { get; set; } /// <summary> /// 注册资本 /// </summary> public string RegCap { set; get; } /// <summary> /// 行业领域 /// </summary> public string IndcodeNameLv2 { get; set; } /// <summary> /// 省 /// </summary> public string Province { get; set; } /// <summary> /// 市 /// </summary> public string City { get; set; } /// <summary> /// 网址 /// </summary> public string Weburl { get; set; } /// <summary> /// 评级 /// </summary> public string Rating { get; set; } /// <summary> /// /// </summary> public int CompanyInfoId { get; set; } #endregion Model #region 导航属性 public virtual CompanyInfo CompanyInfo { get; set; } #endregion } public partial class LegInfo : SpiderModel { public LegInfo() { } #region Model /// <summary> /// /// </summary> public int Id { get; set; } /// <summary> /// /// </summary> public string BlicNo { get; set; } /// <summary> /// /// </summary> public string BlicType { get; set; } /// <summary> /// /// </summary> public string ItemId { get; set; } /// <summary> /// /// </summary> public string Inv { get; set; } /// <summary> /// /// </summary> public string InvType { get; set; } /// <summary> /// /// </summary> public int CompanyInfoId { get; set; } public string CreateTimeStr { get; set; } public string MoneyRange { get; set; } public string Renjiao { get; set; } #endregion Model #region 导航属性 /// <summary> /// 导航属性,公司。 /// </summary> public virtual CompanyInfo CompanyInfo { get; set; } #endregion }
先破解验证码,获取需要查询的公司的URL,然后抓取公司详情也的HTML(过程略);关键代码有两个方法GetBaseInfo和GetLegInfoes
如下:
/// <summary> /// 获取工商基本数据 /// </summary> /// <param name="url"></param> /// <param name="companyInfo"></param> public static BaseInfo GetGsxtInfo(string url, out string html) { HttpItem item = new HttpItem() { URL = url,//URL 必需项 Method = "get", Referer = "http://www.gsxt.gov.cn/corp-query-homepage.html", Timeout = }; html = GetHtml(item); string companyName = GetXpathNode(html, "//h1[@class=\"fullName\"]"); string companyNo = GetXpathNode(html, "//*[@class=\"nameBoxColor\"]"); if (companyNo != "") { //CompanyInfo companyInfo = new CompanyInfo(); //companyInfo.CompanyName = companyName; //companyInfo.CompanyNo = companyNo; //companyInfo.State = 1; //companyInfo.AddTime = DateTime.Now; //companyInfo.NextTime = DateTime.Now; //companyInfo.BaseInfos = new List<BaseInfo>(); var baseInfo = new BaseInfo(); baseInfo.EntName = companyName; baseInfo.RegNo = companyNo; baseInfo.ApprDate = GetXpathNode(html, "//*[@class=\"companyDetail clearfix\"]/span[4]/span[1]"); baseInfo.RegState = GetXpathNode(html, "//*[@class=\"companyStatus\"]"); baseInfo.EntType = GetXpathNode(html, "//div[@class=\"overview\"]/dl[3]/dd[1]"); baseInfo.Lerep = GetXpathNode(html, "//div[@class=\"overview\"]/dl[4]/dd[1]"); baseInfo.RegCap = GetXpathNode(html, "//div[@class=\"overview\"]/dl[5]/dd[1]"); baseInfo.OpFrom = GetXpathNode(html, "//div[@class=\"overview\"]/dl[7]/dd[1]"); baseInfo.OpTo = GetXpathNode(html, "//div[@class=\"overview\"]/dl[8]/dd[1]"); baseInfo.RegOrg = GetXpathNode(html, "//*[@class=\"companyDetail clearfix\"]/span[3]/span[1]"); baseInfo.EstDate = GetXpathNode(html, "//div[@class=\"overview\"]/dl[10]/dd[1]"); baseInfo.Dom = GetXpathNode(html, "//div[@class=\"overview\"]/dl[12]/dd[1]"); baseInfo.OpScope = GetXpathNode(html, "//div[@class=\"overview\"]/dl[13]/dd"); return baseInfo; } else { return null; } } /// <summary> /// 股东信息 /// </summary> /// <param name="html"></param> /// <param name="companyInfo"></param> /// <param name="draw"></param> /// <param name="start"></param> , ) { string url = string.Format("http://www.gsxt.gov.cn{0}", GetFirstInnerText(html, "var shareholderUrl = \"", "\"")); //HttpHelper http = new HttpHelper(); HttpItem item = new HttpItem() { URL = url,//URL 必需项 Method = "post", Referer = "http://www.gsxt.gov.cn/corp-query-search-1.html", Postdata = string.Format("draw={0}&start={1}&length=5", draw, start), ContentType = "application/x-www-form-urlencoded", Timeout = }; string rhtml = GetHtml(item); if (rhtml.Equals("")) { return; } var legInfoesListPage = JObject.Parse(rhtml); var legInfoesListList = legInfoesListPage["data"].ToList(); //删除数据库中的数据 //if (draw == 1) //{ // if (legInfoesListList.Count > 0) // { // foreach (var leginfo in companyInfo.LegInfos.ToList()) // { // companyInfo.LegInfos.Remove(leginfo); // } // } //} //add foreach (var legInfoes in legInfoesListList) { reflegInfos.Add(new LegInfo { BlicNo = GetText(legInfoes["bLicNo"].ToString().Replace("\"", "")), BlicType = legInfoes["blicType_CN"].ToString().Replace("\"", ""), ItemId = legInfoes["invId"].ToString().Replace("\"", ""), Inv = legInfoes["inv"].ToString().Replace("\"", ""), InvType = GetText(legInfoes["invType_CN"].ToString().Replace("\"", "")) }); } ///下页 if (int.Parse(legInfoesListPage["totalPage"].ToString()) > draw) //获取下一页的数据 { draw++; start += ; Console.WriteLine(string.Format("查询股东信息第{0}页", draw)); GetLegInfoes(html, ref reflegInfos, draw, start); } }
到这里为了完成任务写的代码,如果需要对代码让它更加优美,就需要用IOC的模式是重构它
先创建父类:
public class SpiderModel { public SpiderModel() { } public SpiderModel(JToken token) { ToObje(token); } public virtual void ToObje(JToken token) { } public virtual SpiderModel ToObje(string html) { return new SpiderModel(); } /// <summary> /// Xpath获取值 /// </summary> /// <param name="html"></param> /// <param name="xpath"></param> /// <returns></returns> public static string GetXpathNode(string html, string xpath) { string result = string.Empty; #region Xpath提取 try { HtmlDocument htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(html); HtmlNode node = htmlDoc.DocumentNode.SelectSingleNode(xpath); if (node != null) { result = node.InnerHtml; result = new Regex("\\t", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, string.Empty); result = TextRemover.RemoveHTML(result);//去除HTML标签 result = TextRemover.RemoveWhiteSpace(result).Trim();//去空白字符 } } catch (Exception) { } return result; #endregion } public static string GetText(string result) { result = new Regex(@"<(p|br)[^<]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, "[$1]"); result = new Regex("\\[p]", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, "\r\n\r\n"); result = new Regex("\\[br]", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, "\r\n"); result = new Regex("\\t", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, " "); result = TextRemover.RemoveHTML(result);//去除HTML标签 result = result.Replace("+", ""); result = result.Trim(); result = RegexHelper.RegexFilter(result.ToString().Replace("\"", ""), "([a-zA-Z0-9]+)", false, RegexOptions.None); return result; } }
然后实体BaseInfo(基本信息)和LegInfo(股东信息)继承自SpiderModel
然后给BaseInfo(基本信息)和LegInfo(股东信息)重写函数
BaseInfo:
public override SpiderModel ToObje(string html) { string companyName = GetXpathNode(html, "//h1[@class=\"fullName\"]"); string companyNo = GetXpathNode(html, "//*[@class=\"nameBoxColor\"]"); if (companyNo != "") { EntName = companyName; RegNo = companyNo; ApprDate = GetXpathNode(html, "//*[@class=\"companyDetail clearfix\"]/span[4]/span[1]"); RegState = GetXpathNode(html, "//*[@class=\"companyStatus\"]"); EntType = GetXpathNode(html, "//div[@class=\"overview\"]/dl[3]/dd[1]"); Lerep = GetXpathNode(html, "//div[@class=\"overview\"]/dl[4]/dd[1]"); RegCap = GetXpathNode(html, "//div[@class=\"overview\"]/dl[5]/dd[1]"); OpFrom = GetXpathNode(html, "//div[@class=\"overview\"]/dl[7]/dd[1]"); OpTo = GetXpathNode(html, "//div[@class=\"overview\"]/dl[8]/dd[1]"); RegOrg = GetXpathNode(html, "//*[@class=\"companyDetail clearfix\"]/span[3]/span[1]"); EstDate = GetXpathNode(html, "//div[@class=\"overview\"]/dl[10]/dd[1]"); Dom = GetXpathNode(html, "//div[@class=\"overview\"]/dl[12]/dd[1]"); OpScope = GetXpathNode(html, "//div[@class=\"overview\"]/dl[13]/dd"); } return this; }
LegInfo:
public override void ToObje(JToken token) { BlicNo = SpiderModel.GetText(token["bLicNo"].ToString().Replace("\"", "")); BlicType = token["blicType_CN"].ToString().Replace("\"", ""); ItemId = token["invId"].ToString().Replace("\"", ""); Inv = token["inv"].ToString().Replace("\"", ""); InvType = GetText(token["invType_CN"].ToString().Replace("\"", "")); }
最后要一个IOC管理类
public class SpiderManage { public SpiderManage(HttpItem item) { this.Item = item; } public SpiderManage(HttpItem item,SpiderModel spiderModel) { this.Item = item; this.SpiderModel = spiderModel; } public string Html { get; set; } public HttpItem Item { get; set; } public List<SpiderModel> SpiderModelList{ get; set; } public SpiderModel SpiderModel { get; set; } public virtual string GetHtml() { ; ) { i--; HttpHelper http = new HttpHelper(); HttpResult result; object oj = new object(); lock (oj) { Thread.Sleep(); result = http.GetHtml(Item); } if (result.StatusCode == System.Net.HttpStatusCode.OK) { string rhtml = result.Html; if (!rhtml.Equals("<script>window.location.href='/index/invalidLink'</script>")) { Html = result.Html; return Html; } } } Html = ""; return Html; } public SpiderModel GetOjb() { return SpiderModel.ToObje(Html); } public void toList() { // SpiderModelList //SpiderModel } }
最后面我就只要 List<SpiderManage> sManageList用于保存对象就可以了
重新改写前面的GetBaseInfo和GetLegInfoes函数。
public static List<SpiderManage> sManageList = new List<SpiderManage>(); ////////////////////////////////////////////// , ) { string url = string.Format("http://www.gsxt.gov.cn{0}", GetFirstInnerText(html, "var shareholderUrl = \"", "\"")); HttpItem item = new HttpItem() { URL = url,//URL 必需项 Method = "post", Referer = "http://www.gsxt.gov.cn/corp-query-search-1.html", Postdata = string.Format("draw={0}&start={1}&length=5", draw, start), ContentType = "application/x-www-form-urlencoded", Timeout = }; SpiderManage sManage = new SpiderManage(item); sManage.SpiderModel = new LegInfo(); sManage.GetHtml(); string rhtml = sManage.Html; if (rhtml.Equals("")) { return; } var legInfoesListPage = JObject.Parse(rhtml); sManageList.Add(sManage); //var legInfoesListList = legInfoesListPage["data"].ToList(); //删除数据库中的数据 //add //foreach (var legInfoes in legInfoesListList) // { // reflegInfos.Add(new LegInfo { BlicNo = GetText(legInfoes["bLicNo"].ToString().Replace("\"", "")), BlicType = legInfoes["blicType_CN"].ToString().Replace("\"", ""), ItemId = legInfoes["invId"].ToString().Replace("\"", ""), Inv = legInfoes["inv"].ToString().Replace("\"", ""), InvType = GetText(legInfoes["invType_CN"].ToString().Replace("\"", "")) }); // } ///下页 while (int.Parse(legInfoesListPage["totalPage"].ToString()) > draw) //获取下一页的数据 { draw++; start += ; sManageList.Add(new SpiderManage(new HttpItem() { URL = url,//URL 必需项 Method = "post", Referer = "http://www.gsxt.gov.cn/corp-query-search-1.html", Postdata = string.Format("draw={0}&start={1}&length=5", draw, start), ContentType = "application/x-www-form-urlencoded", Timeout = }, new LegInfo())); //Console.WriteLine(string.Format("查询股东信息第{0}页", draw)); //GetLegInfoes(html, ref reflegInfos, draw, start); } }
后面怎么用就不讨论了,只要是把sManageList拿过去调度分配抓取就可以了
Ioc在重构代码中的应用的更多相关文章
- 代码重构 & 代码中的坏味道
1.重构 1.1 为什么要重构 1.1.1 改进程序设计 程序员为了快速完成任务,在没有完全理解整体架构之前就开始写代码, 导致程序逐渐失去自己的结构.重构则帮助重新组织代码,重新清晰的体现 程序结构 ...
- 要心中有“数”——C语言初学者代码中的常见错误与瑕疵(8)
在 C语言初学者代码中的常见错误与瑕疵(7) 中,我给出的重构代码中存在BUG.这个BUG是在飞鸟_Asuka网友指出“是不是时间复杂度比较大”,并说他“第一眼看到我就想把它当成一个数学问题来做”之后 ...
- C语言初学者代码中的常见错误与瑕疵(7)
问题: 矩形的个数 在一个3*2的矩形中,可以找到6个1*1的矩形,4个2*1的矩形3个1*2的矩形,2个2*2的矩形,2个3*1的矩形和1个3*2的矩形,总共18个矩形.给出A,B,计算可以从中找到 ...
- Rafy 领域实体框架设计 - 重构 ORM 中的 Sql 生成
前言 Rafy 领域实体框架作为一个使用领域驱动设计作为指导思想的开发框架,必然要处理领域实体到数据库表之间的映射,即包含了 ORM 的功能.由于在 09 年最初设计时,ORM 部分的设计并不是最重要 ...
- Winform打砖块游戏制作step by step第5节---重构代码,利用继承多态
一 引子 为了让更多的编程初学者,轻松愉快地掌握面向对象的思考方法,对象继承和多态的妙用,故推出此系列随笔,还望大家多多支持. 二 本节内容---重构代码,利用继承多态 1. 主界面截图如下: 2. ...
- 一个超复杂的间接递归——C语言初学者代码中的常见错误与瑕疵(6)
问题: 问题出处见 C语言初学者代码中的常见错误与瑕疵(5) . 在该文的最后,曾提到完成的代码还有进一步改进的余地.本文完成了这个改进.所以本文讨论的并不是初学者代码中的常见错误与瑕疵,而是对我自己 ...
- C语言初学者代码中的常见错误与瑕疵(5)
问题: 素数 在世博园某信息通信馆中,游客可利用手机等终端参与互动小游戏,与虚拟人物Kr. Kong 进行猜数比赛. 当屏幕出现一个整数X时,若你能比Kr. Kong更快的发出最接近它的素数答案,你将 ...
- 分数的加减法——C语言初学者代码中的常见错误与瑕疵(12)
前文链接:分数的加减法——C语言初学者代码中的常见错误与瑕疵(11) 重构 题目的修正 我抛弃了原题中“其中a, b, c, d是一个0-9的整数”这样的前提条件,因为这种限制毫无必要.只假设a, b ...
- C语言初学者代码中的常见错误与瑕疵(9)
题目 字母的个数 现在给你一个由小写字母组成字符串,要你找出字符串中出现次数最多的字母,如果出现次数最多字母有多个那么输出最小的那个. 输入:第一行输入一个正整数T(0<T<25) 随后T ...
随机推荐
- MATLAB绘制等高线和梯度场
clear;clc;close all [X,Y] = meshgrid(-:.:); % 产生网格数据X和Y Z = X.*exp(-X.^ - Y.^); % 计算网格点处曲面上的Z值 [DX,D ...
- Hadoop权威指南:HDFS-数据流
Hadoop权威指南:HDFS-数据流 [TOC] 剖析文件读取 客户端通过调用FileSystem对象的open()方法来打开希望读取的文件,对于HDFS来说, 这个对象是分布式文件系统的一个实例 ...
- 游戏音频技术备忘 (三) 集成Wwise到Unreal Engine
当前受众较广的商业游戏引擎有 Unreal Engine.Unity.cocos2d-x等,在音频领域的第三方中间件则有Wwise.FMOD.Criware等,言多且烦,我们首先集成Wwise到 Un ...
- 制作jar文件
一.制作可运行jar文件 使用java的swing.awt制作了一个简单的界面交互模块.程序打成jar包后,能双击运行,制作过程: 1.eclipse →properties →Export,选择ja ...
- 《Effective C#中文版:改善C#程序的50种方法》读书笔记
作者: suyan010203 来源: 博客园 发布时间: 2011-07-09 14:47 阅读: 8988 次 推荐: 4 原文链接 [收藏] 从去 ...
- javaweb log4j显示完整sql日志
javaweb显示完整sql日志 所需jar包: log4j-1.2.17.jar log4jdbc-1.2.jar slf4j-api-1.7.12.jar slf4j-log4j12-1.7.12 ...
- nodejs笔记1 ----关于express不是本地命令
1,npm install -g express安装express框架 2,npm install -g express-generator安装命令工具 3,express --help 安装完成
- Android系统之灯光系统--通知灯深入分析
Android通知灯的深入分析 通知的类别 声音 振动 闪灯 APP如何发出通知灯请求 getSystemService(通知服务) 构造notification 类别 其他参数(颜色,onMS,of ...
- Odd Numbers of Divisors
给出一个正奇数K,两个正整数low,high. 有多少整数属于[low, high],且包含K个因子. 数据 C(0 < C < 1e5),测试样例数. (1 < K < 10 ...
- C++ 头文件系列(sstream)
1. 简介 这个头文件主要定义了基于字符串类(string类)的流的4个模版: basic_stringbuf basic_istringstream basic_ostringstream basi ...