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 ...
随机推荐
- ios NSString拼接方法总结
NSString* string; // 结果字符串 02 NSString* string1, string2; //已存在的字符串,需要将string1和string2连接起来 03 04 / ...
- 《JAVASCRIPT高级程序设计》原生拖放和媒体元素
一.原生拖放 最早在网页中引入javascript拖放功能的是IE4,当时,网页中只有两种对象可以拖放:图像和某些文本.而现在,几乎网页中的任何元素都可以拖放以及作为放置目标.下面介绍一些与拖放相关的 ...
- WPF开发进阶 - Fody/PropertyChanged(一)
INotifyPropertyChanged 在WPF MVVM模式开发中,实现INotifyPropertyChanged的ViewModel是非常重要且常见的类: public class Mai ...
- 启动activity与使用Intent通信机制解析
我们都知道,一个activity启动另一个activity最简单的方式就是使用startActivity方法: public void startActivity (Intent intent) 但是 ...
- webservice_模拟报文测试
一.WebService测试小工具STORM 二.利用MyEclipse的WebService视图调用webservice Ø 除了客户端生成代码编写程序调用之外.还可以用MyEclipse提供 ...
- 一次Redis 的性能测试和问题
[我的问题]:请教个问题,我在本机搭建linux虚拟机+redis 3.2.6,然后在本机物理机上面测试虚拟机的redis性能,如下VM配置参数做测试,redis 的性能好像不算太好,问题待排查的两点 ...
- 【踩坑速记】MIUI系统BUG,调用系统相机拍照可能会带给你的一系列坑,将拍照适配方案进行到底!
一.写在前面 前几天也是分享了一些学习必备干货(还没关注的,赶紧入坑:传送门),也好久没有与大家探讨技术方案了,心里也是挺痒痒的,这不,一有点闲暇之时,就迫不及待把最近测出来的坑分享给大家. 提起An ...
- Python抓取第一网贷中国网贷理财每日收益率指数
链接:http://www.p2p001.com/licai/index/id/147.html 所需获取数据链接类似于:http://www.p2p001.com/licai/shownews/id ...
- 读书笔记 effective c++ Item 14 对资源管理类的拷贝行为要谨慎
1. 自己实现一个资源管理类 Item 13中介绍了 “资源获取之时也是初始化之时(RAII)”的概念,这个概念被当作资源管理类的“脊柱“,也描述了auto_ptr和tr1::shared_ptr是如 ...
- JAVA高级编程序——JDBC(连接mysql数据库)——(一)
java要想连接数据库,就要用JDBC(java database connection),用这个jar包 (mysql-connector-java-xxx-xx-bin.jar) sun公司为我们 ...