最近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 ...
随机推荐
-
Dedecms去掉URL中a目录的方法
本文实例讲述了Dedecms去掉URL中a目录的方法.分享给大家,供大家参考.具体分析如下: 使用dedecms的朋友可能会发现自己的URL目录生成是会自动带有一个/A/目录了,那么要如何去掉URL中 ...
-
Java for LeetCode 076 Minimum Window Substring
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
-
掌上PDA无线下单 移动开单设备 手持POS终端打印扫描开单进销软件
您公司是否存在以下问题吗? ◆ 接单员对价钱是否能记住?接单员是否知道库存? ◆ 接单员是否向客户推介优势产品或新产品? ◆ 接单员是否知道客户为什么有的产品再也没有给我们拿货? ◆ 退货时为什么会退 ...
-
Django文档——Model字段类型(Field Types)
大部分内容参考自http://wrongwaycn.github.io/django11/topics/db/models/index.html#topics-db-models ,内容是django ...
-
团体程序设计天梯赛-练习集L1-022. 奇偶分家
L1-022. 奇偶分家 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定N个正整数,请统计奇数和偶数各有多少个? 输入格式 ...
-
实时Bug检测工具Bugsnag发布API更新
原文地址: http://www.uml.org.cn/itnews/2013082609.asp 在应用开发过程中,开发者常常会碰到一个非常头疼的问题,就是应用崩溃.而Bugsnag可以很好地解决这 ...
-
android中Sensor 工作流程
JAVA 程序 我们使用 sensor 接口一般只要注册一下 SensorListener 像下面这样 ************************************************ ...
-
Y7000联想拯救者gtx1050Ti安装cuda9.0
安装cuda经常会遇到安装失败的问题,原因大部分都是由于驱动不一致引起的,接下来我们分两步讲解 1. 安装驱动失败 原因:nvidia官网提供的驱动都是通用的,针对特殊设备可能出现不兼容问题,方法很简 ...
-
Daily Scrum5 11.7
今日任务: 姓名 任务 时长 徐钧鸿 学习了java连接sqlserver的方法并且实现了连接池 2h 张艺 继续完成和用户管理有关的类的移植(Register.Success.Validate等) ...
-
SharePoint 2013 - Host-named Site Collection
1. 详细操作可参考此文章 的 Deployment and configuration for host-named site collections区域,简单来说,需要以下三行PowerShell ...