最近lz在写抓工商公式系统(http://www.gsxt.gov.cn/index.html)的爬虫,其中的难点就是在怎么过极验验证码,搞的我不要不要的!如下:

简直是各种坑,被搞的死去活来以后还是解决了。现在回到主题!

  我们不是要抓工商公式系统的数据吗?所以我们先建两个实体BaseInfo(基本信息)和LegInfo(股东信息)

  1. public partial class BaseInfo
  2. {
  3. public BaseInfo()
  4. { }
  5. public BaseInfo(string html)
  6. { }
  7. #region Model
  8. /// <summary>
  9. ///
  10. /// </summary>
  11. public int Id
  12. {
  13. get;
  14. set;
  15. }
  16. /// <summary>
  17. /// 成立日期
  18. /// </summary>
  19. public string ApprDate
  20. {
  21. get;
  22. set;
  23. }
  24. /// <summary>
  25. /// 公司全称
  26. /// </summary>
  27. public string EntName
  28. {
  29. get;
  30. set;
  31. }
  32.  
  33. /// <summary>
  34. /// 公司类型
  35. /// </summary>
  36. public string EntType
  37. {
  38. get;
  39. set;
  40. }
  41. /// <summary>
  42. /// 住所
  43. /// </summary>
  44. public string Dom
  45. {
  46. get;
  47. set;
  48. }
  49. /// <summary>
  50. /// 核准日期
  51. /// </summary>
  52. public string EstDate
  53. {
  54. get;
  55. set;
  56. }
  57. /// <summary>
  58. /// 法人
  59. /// </summary>
  60. public string Lerep
  61. {
  62. get;
  63. set;
  64. }
  65. /// <summary>
  66. /// 营业期限自
  67. /// </summary>
  68. public string OpFrom
  69. {
  70. get;
  71. set;
  72. }
  73. /// <summary>
  74. /// 营业期限至
  75. /// </summary>
  76. public string OpTo
  77. {
  78. get;
  79. set;
  80. }
  81. /// <summary>
  82. /// 经营范围
  83. /// </summary>
  84. public string OpScope
  85. {
  86. get;
  87. set;
  88. }
  89. /// <summary>
  90. /// 注册号
  91. /// </summary>
  92. public string RegNo
  93. {
  94. get;
  95. set;
  96. }
  97. /// <summary>
  98. /// 登记机关
  99. /// </summary>
  100. public string RegOrg
  101. {
  102. get;
  103. set;
  104. }
  105. /// <summary>
  106. /// 登记状态
  107. /// </summary>
  108. public string RegState
  109. {
  110. get;
  111. set;
  112. }
  113. /// <summary>
  114. /// 注册资本
  115. /// </summary>
  116. public string RegCap
  117. {
  118. set;
  119. get;
  120. }
  121. /// <summary>
  122. /// 行业领域
  123. /// </summary>
  124. public string IndcodeNameLv2 { get; set; }
  125. /// <summary>
  126. /// 省
  127. /// </summary>
  128. public string Province { get; set; }
  129. /// <summary>
  130. /// 市
  131. /// </summary>
  132. public string City { get; set; }
  133. /// <summary>
  134. /// 网址
  135. /// </summary>
  136. public string Weburl { get; set; }
  137. /// <summary>
  138. /// 评级
  139. /// </summary>
  140. public string Rating { get; set; }
  141.  
  142. /// <summary>
  143. ///
  144. /// </summary>
  145. public int CompanyInfoId
  146. {
  147. get;
  148. set;
  149. }
  150. #endregion Model
  151. #region 导航属性
  152.  
  153. public virtual CompanyInfo CompanyInfo { get; set; }
  154. #endregion
  155. }
  156.  
  157. public partial class LegInfo : SpiderModel
  158. {
  159. public LegInfo()
  160. { }
  161. #region Model
  162. /// <summary>
  163. ///
  164. /// </summary>
  165. public int Id
  166. {
  167. get;
  168. set;
  169. }
  170. /// <summary>
  171. ///
  172. /// </summary>
  173. public string BlicNo
  174. {
  175. get;
  176. set;
  177. }
  178. /// <summary>
  179. ///
  180. /// </summary>
  181. public string BlicType
  182. {
  183. get;
  184. set;
  185. }
  186. /// <summary>
  187. ///
  188. /// </summary>
  189. public string ItemId
  190. {
  191. get;
  192. set;
  193. }
  194. /// <summary>
  195. ///
  196. /// </summary>
  197. public string Inv
  198. {
  199. get;
  200. set;
  201. }
  202. /// <summary>
  203. ///
  204. /// </summary>
  205. public string InvType
  206. {
  207. get;
  208. set;
  209. }
  210. /// <summary>
  211. ///
  212. /// </summary>
  213. public int CompanyInfoId
  214. {
  215. get;
  216. set;
  217. }
  218. public string CreateTimeStr { get; set; }
  219. public string MoneyRange { get; set; }
  220. public string Renjiao { get; set; }
  221. #endregion Model
  222. #region 导航属性
  223. /// <summary>
  224. /// 导航属性,公司。
  225. /// </summary>
  226. public virtual CompanyInfo CompanyInfo { get; set; }
  227. #endregion
  228. }

先破解验证码,获取需要查询的公司的URL,然后抓取公司详情也的HTML(过程略);关键代码有两个方法GetBaseInfo和GetLegInfoes

如下:

  1. /// <summary>
  2. /// 获取工商基本数据
  3. /// </summary>
  4. /// <param name="url"></param>
  5. /// <param name="companyInfo"></param>
  6. public static BaseInfo GetGsxtInfo(string url, out string html)
  7. {
  8. HttpItem item = new HttpItem()
  9. {
  10. URL = url,//URL 必需项
  11. Method = "get",
  12. Referer = "http://www.gsxt.gov.cn/corp-query-homepage.html",
  13. Timeout =
  14. };
  15. html = GetHtml(item);
  16.  
  17. string companyName = GetXpathNode(html, "//h1[@class=\"fullName\"]");
  18. string companyNo = GetXpathNode(html, "//*[@class=\"nameBoxColor\"]");
  19.  
  20. if (companyNo != "")
  21. {
  22. //CompanyInfo companyInfo = new CompanyInfo();
  23.  
  24. //companyInfo.CompanyName = companyName;
  25. //companyInfo.CompanyNo = companyNo;
  26. //companyInfo.State = 1;
  27. //companyInfo.AddTime = DateTime.Now;
  28. //companyInfo.NextTime = DateTime.Now;
  29. //companyInfo.BaseInfos = new List<BaseInfo>();
  30. var baseInfo = new BaseInfo();
  31. baseInfo.EntName = companyName;
  32. baseInfo.RegNo = companyNo;
  33. baseInfo.ApprDate = GetXpathNode(html, "//*[@class=\"companyDetail clearfix\"]/span[4]/span[1]");
  34. baseInfo.RegState = GetXpathNode(html, "//*[@class=\"companyStatus\"]");
  35. baseInfo.EntType = GetXpathNode(html, "//div[@class=\"overview\"]/dl[3]/dd[1]");
  36. baseInfo.Lerep = GetXpathNode(html, "//div[@class=\"overview\"]/dl[4]/dd[1]");
  37. baseInfo.RegCap = GetXpathNode(html, "//div[@class=\"overview\"]/dl[5]/dd[1]");
  38. baseInfo.OpFrom = GetXpathNode(html, "//div[@class=\"overview\"]/dl[7]/dd[1]");
  39. baseInfo.OpTo = GetXpathNode(html, "//div[@class=\"overview\"]/dl[8]/dd[1]");
  40. baseInfo.RegOrg = GetXpathNode(html, "//*[@class=\"companyDetail clearfix\"]/span[3]/span[1]");
  41. baseInfo.EstDate = GetXpathNode(html, "//div[@class=\"overview\"]/dl[10]/dd[1]");
  42. baseInfo.Dom = GetXpathNode(html, "//div[@class=\"overview\"]/dl[12]/dd[1]");
  43. baseInfo.OpScope = GetXpathNode(html, "//div[@class=\"overview\"]/dl[13]/dd");
  44. return baseInfo;
  45.  
  46. }
  47. else
  48. {
  49. return null;
  50. }
  51. }
  52.  
  53. /// <summary>
  54. /// 股东信息
  55. /// </summary>
  56. /// <param name="html"></param>
  57. /// <param name="companyInfo"></param>
  58. /// <param name="draw"></param>
  59. /// <param name="start"></param>
  60. , )
  61. {
  62. string url = string.Format("http://www.gsxt.gov.cn{0}", GetFirstInnerText(html, "var shareholderUrl = \"", "\""));
  63. //HttpHelper http = new HttpHelper();
  64. HttpItem item = new HttpItem()
  65. {
  66. URL = url,//URL 必需项
  67. Method = "post",
  68. Referer = "http://www.gsxt.gov.cn/corp-query-search-1.html",
  69. Postdata = string.Format("draw={0}&start={1}&length=5", draw, start),
  70. ContentType = "application/x-www-form-urlencoded",
  71. Timeout =
  72. };
  73.  
  74. string rhtml = GetHtml(item); if (rhtml.Equals("")) { return; }
  75.  
  76. var legInfoesListPage = JObject.Parse(rhtml);
  77.  
  78. var legInfoesListList = legInfoesListPage["data"].ToList();
  79. //删除数据库中的数据
  80. //if (draw == 1)
  81. //{
  82. // if (legInfoesListList.Count > 0)
  83. // {
  84. // foreach (var leginfo in companyInfo.LegInfos.ToList())
  85. // {
  86. // companyInfo.LegInfos.Remove(leginfo);
  87. // }
  88. // }
  89. //}
  90. //add
  91. foreach (var legInfoes in legInfoesListList)
  92. {
  93. 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("\"", "")) });
  94. }
  95. ///下页
  96. if (int.Parse(legInfoesListPage["totalPage"].ToString()) > draw) //获取下一页的数据
  97. {
  98. draw++;
  99. start += ;
  100. Console.WriteLine(string.Format("查询股东信息第{0}页", draw));
  101. GetLegInfoes(html, ref reflegInfos, draw, start);
  102. }
  103.  
  104. }

到这里为了完成任务写的代码,如果需要对代码让它更加优美,就需要用IOC的模式是重构它

先创建父类:

  1. public class SpiderModel
  2. {
  3. public SpiderModel()
  4. {
  5. }
  6.  
  7. public SpiderModel(JToken token)
  8. {
  9. ToObje(token);
  10. }
  11. public virtual void ToObje(JToken token)
  12. {
  13. }
  14. public virtual SpiderModel ToObje(string html)
  15. {
  16. return new SpiderModel();
  17. }
  18. /// <summary>
  19. /// Xpath获取值
  20. /// </summary>
  21. /// <param name="html"></param>
  22. /// <param name="xpath"></param>
  23. /// <returns></returns>
  24. public static string GetXpathNode(string html, string xpath)
  25. {
  26. string result = string.Empty;
  27. #region Xpath提取
  28. try
  29. {
  30. HtmlDocument htmlDoc = new HtmlDocument();
  31. htmlDoc.LoadHtml(html);
  32. HtmlNode node = htmlDoc.DocumentNode.SelectSingleNode(xpath);
  33. if (node != null)
  34. {
  35. result = node.InnerHtml;
  36. result = new Regex("\\t", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, string.Empty);
  37. result = TextRemover.RemoveHTML(result);//去除HTML标签
  38. result = TextRemover.RemoveWhiteSpace(result).Trim();//去空白字符
  39. }
  40. }
  41. catch (Exception)
  42. {
  43. }
  44. return result;
  45. #endregion
  46. }
  47. public static string GetText(string result)
  48. {
  49. result = new Regex(@"<(p|br)[^<]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, "[$1]");
  50. result = new Regex("\\[p]", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, "\r\n\r\n");
  51. result = new Regex("\\[br]", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, "\r\n");
  52. result = new Regex("\\t", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(result, " ");
  53. result = TextRemover.RemoveHTML(result);//去除HTML标签
  54. result = result.Replace("+", "");
  55. result = result.Trim();
  56. result = RegexHelper.RegexFilter(result.ToString().Replace("\"", ""), "([a-zA-Z0-9]+)", false, RegexOptions.None);
  57. return result;
  58. }
  59. }

然后实体BaseInfo(基本信息)和LegInfo(股东信息)继承自SpiderModel

然后给BaseInfo(基本信息)和LegInfo(股东信息)重写函数

BaseInfo:

  1. public override SpiderModel ToObje(string html)
  2. {
  3. string companyName = GetXpathNode(html, "//h1[@class=\"fullName\"]");
  4. string companyNo = GetXpathNode(html, "//*[@class=\"nameBoxColor\"]");
  5.  
  6. if (companyNo != "")
  7. {
  8. EntName = companyName;
  9. RegNo = companyNo;
  10. ApprDate = GetXpathNode(html, "//*[@class=\"companyDetail clearfix\"]/span[4]/span[1]");
  11. RegState = GetXpathNode(html, "//*[@class=\"companyStatus\"]");
  12. EntType = GetXpathNode(html, "//div[@class=\"overview\"]/dl[3]/dd[1]");
  13. Lerep = GetXpathNode(html, "//div[@class=\"overview\"]/dl[4]/dd[1]");
  14. RegCap = GetXpathNode(html, "//div[@class=\"overview\"]/dl[5]/dd[1]");
  15. OpFrom = GetXpathNode(html, "//div[@class=\"overview\"]/dl[7]/dd[1]");
  16. OpTo = GetXpathNode(html, "//div[@class=\"overview\"]/dl[8]/dd[1]");
  17. RegOrg = GetXpathNode(html, "//*[@class=\"companyDetail clearfix\"]/span[3]/span[1]");
  18. EstDate = GetXpathNode(html, "//div[@class=\"overview\"]/dl[10]/dd[1]");
  19. Dom = GetXpathNode(html, "//div[@class=\"overview\"]/dl[12]/dd[1]");
  20. OpScope = GetXpathNode(html, "//div[@class=\"overview\"]/dl[13]/dd");
  21. }
  22. return this;
  23.  
  24. }

LegInfo:

  1. public override void ToObje(JToken token)
  2. {
  3. BlicNo = SpiderModel.GetText(token["bLicNo"].ToString().Replace("\"", ""));
  4. BlicType = token["blicType_CN"].ToString().Replace("\"", "");
  5. ItemId = token["invId"].ToString().Replace("\"", "");
  6. Inv = token["inv"].ToString().Replace("\"", "");
  7. InvType = GetText(token["invType_CN"].ToString().Replace("\"", ""));
  8. }

最后要一个IOC管理类

  1. public class SpiderManage
  2. {
  3. public SpiderManage(HttpItem item)
  4. {
  5. this.Item = item;
  6. }
  7. public SpiderManage(HttpItem item,SpiderModel spiderModel)
  8. {
  9. this.Item = item;
  10. this.SpiderModel = spiderModel;
  11. }
  12. public string Html { get; set; }
  13. public HttpItem Item { get; set; }
  14. public List<SpiderModel> SpiderModelList{ get; set; }
  15. public SpiderModel SpiderModel { get; set; }
  16. public virtual string GetHtml()
  17. {
  18. ;
  19. )
  20. {
  21. i--;
  22. HttpHelper http = new HttpHelper();
  23. HttpResult result;
  24. object oj = new object();
  25. lock (oj)
  26. {
  27. Thread.Sleep();
  28. result = http.GetHtml(Item);
  29. }
  30. if (result.StatusCode == System.Net.HttpStatusCode.OK)
  31. {
  32. string rhtml = result.Html;
  33. if (!rhtml.Equals("<script>window.location.href='/index/invalidLink'</script>"))
  34. {
  35. Html = result.Html;
  36. return Html;
  37. }
  38. }
  39. }
  40. Html = "";
  41. return Html;
  42. }
  43. public SpiderModel GetOjb()
  44. {
  45. return SpiderModel.ToObje(Html);
  46. }
  47. public void toList()
  48. {
  49. // SpiderModelList
  50. //SpiderModel
  51. }
  52. }

最后面我就只要 List<SpiderManage> sManageList用于保存对象就可以了

重新改写前面的GetBaseInfo和GetLegInfoes函数。

  1. public static List<SpiderManage> sManageList = new List<SpiderManage>();
  2.  
  3. //////////////////////////////////////////////
  4. , )
  5. {
  6. string url = string.Format("http://www.gsxt.gov.cn{0}", GetFirstInnerText(html, "var shareholderUrl = \"", "\""));
  7. HttpItem item = new HttpItem()
  8. {
  9. URL = url,//URL 必需项
  10. Method = "post",
  11. Referer = "http://www.gsxt.gov.cn/corp-query-search-1.html",
  12. Postdata = string.Format("draw={0}&start={1}&length=5", draw, start),
  13. ContentType = "application/x-www-form-urlencoded",
  14. Timeout =
  15. };
  16. SpiderManage sManage = new SpiderManage(item);
  17. sManage.SpiderModel = new LegInfo();
  18. sManage.GetHtml();
  19.  
  20. string rhtml = sManage.Html;
  21. if (rhtml.Equals(""))
  22. { return; }
  23.  
  24. var legInfoesListPage = JObject.Parse(rhtml);
  25. sManageList.Add(sManage);
  26. //var legInfoesListList = legInfoesListPage["data"].ToList();
  27. //删除数据库中的数据
  28.  
  29. //add
  30. //foreach (var legInfoes in legInfoesListList)
  31. // {
  32. // 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("\"", "")) });
  33. // }
  34. ///下页
  35. while (int.Parse(legInfoesListPage["totalPage"].ToString()) > draw) //获取下一页的数据
  36. {
  37. draw++;
  38. start += ;
  39. sManageList.Add(new SpiderManage(new HttpItem()
  40. {
  41. URL = url,//URL 必需项
  42. Method = "post",
  43. Referer = "http://www.gsxt.gov.cn/corp-query-search-1.html",
  44. Postdata = string.Format("draw={0}&start={1}&length=5", draw, start),
  45. ContentType = "application/x-www-form-urlencoded",
  46. Timeout =
  47. }, new LegInfo()));
  48.  
  49. //Console.WriteLine(string.Format("查询股东信息第{0}页", draw));
  50. //GetLegInfoes(html, ref reflegInfos, draw, start);
  51. }
  52.  
  53. }

后面怎么用就不讨论了,只要是把sManageList拿过去调度分配抓取就可以了

Ioc在重构代码中的应用的更多相关文章

  1. 代码重构 & 代码中的坏味道

    1.重构 1.1 为什么要重构 1.1.1 改进程序设计 程序员为了快速完成任务,在没有完全理解整体架构之前就开始写代码, 导致程序逐渐失去自己的结构.重构则帮助重新组织代码,重新清晰的体现 程序结构 ...

  2. 要心中有“数”——C语言初学者代码中的常见错误与瑕疵(8)

    在 C语言初学者代码中的常见错误与瑕疵(7) 中,我给出的重构代码中存在BUG.这个BUG是在飞鸟_Asuka网友指出“是不是时间复杂度比较大”,并说他“第一眼看到我就想把它当成一个数学问题来做”之后 ...

  3. 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,计算可以从中找到 ...

  4. Rafy 领域实体框架设计 - 重构 ORM 中的 Sql 生成

    前言 Rafy 领域实体框架作为一个使用领域驱动设计作为指导思想的开发框架,必然要处理领域实体到数据库表之间的映射,即包含了 ORM 的功能.由于在 09 年最初设计时,ORM 部分的设计并不是最重要 ...

  5. Winform打砖块游戏制作step by step第5节---重构代码,利用继承多态

    一 引子 为了让更多的编程初学者,轻松愉快地掌握面向对象的思考方法,对象继承和多态的妙用,故推出此系列随笔,还望大家多多支持. 二 本节内容---重构代码,利用继承多态 1. 主界面截图如下: 2.  ...

  6. 一个超复杂的间接递归——C语言初学者代码中的常见错误与瑕疵(6)

    问题: 问题出处见 C语言初学者代码中的常见错误与瑕疵(5) . 在该文的最后,曾提到完成的代码还有进一步改进的余地.本文完成了这个改进.所以本文讨论的并不是初学者代码中的常见错误与瑕疵,而是对我自己 ...

  7. C语言初学者代码中的常见错误与瑕疵(5)

    问题: 素数 在世博园某信息通信馆中,游客可利用手机等终端参与互动小游戏,与虚拟人物Kr. Kong 进行猜数比赛. 当屏幕出现一个整数X时,若你能比Kr. Kong更快的发出最接近它的素数答案,你将 ...

  8. 分数的加减法——C语言初学者代码中的常见错误与瑕疵(12)

    前文链接:分数的加减法——C语言初学者代码中的常见错误与瑕疵(11) 重构 题目的修正 我抛弃了原题中“其中a, b, c, d是一个0-9的整数”这样的前提条件,因为这种限制毫无必要.只假设a, b ...

  9. C语言初学者代码中的常见错误与瑕疵(9)

    题目 字母的个数 现在给你一个由小写字母组成字符串,要你找出字符串中出现次数最多的字母,如果出现次数最多字母有多个那么输出最小的那个. 输入:第一行输入一个正整数T(0<T<25) 随后T ...

随机推荐

  1. [css]《css揭秘》学习笔记(一)

    一.background-clip属性 <html> <head> <meta charset="utf-8"> <title>背景 ...

  2. MongoDB基础之八 备份与恢复

    Mongodb导出与导入 1: 导入/导出可以操作的是本地的mongodb服务器,也可以是远程的.所以,都有如下通用选项:-h host 主机--port port 端口-u username 用户名 ...

  3. SwingBench---ORACLE压力测试工具

    SwingBench---ORACLE压力测试工具 ◆描述SwingBench是Oracle UK的一个员工在一个被抛弃的项目的基础上开发的.目前稳定版本2.5,基于JDK.该工具是免费的,可以在作者 ...

  4. Swift2.0 函数学习笔记

    最近又有点忙,忙着找工作,忙着适应这个新环境.现在好了,上班两周周了,也适应过来了,又有时间安安静静的就行我们前面的学习了.今天这篇笔记,记录的就是函数的使用.下面这些代码基本上是理清楚了函数的额使用 ...

  5. Jquery动态增加行和删除行

    $("#add_5").click(function(){ var str_1="<tr> <td><input type=\"t ...

  6. API模板

    #include <windows.h> #include <windowsx.h> #define DIVISIONS 5 LRESULT CALLBACK WndProc ...

  7. Linux系统(一)文件系统、压缩、打包操作总结

    序言 当前的形势,.Net已经开源,.Net Core 正在跨平台,可见微软巨人在努力,在改变,在进步,在走向春天.从前被微软供作上帝的.Net从业者,如果不打开心扉面向开源,改变自己,那么很可能在不 ...

  8. 自动化测试 -- 通过Cookie跳过登录验证码

    之前写过一篇博客:自动化测试如何解决验证码的问题. http://www.cnblogs.com/fnng/p/3606934.html 介绍了验证码的几种处理方式,最后一种就是通过Cookie跳转过 ...

  9. BZOJ 2142: 礼物

    模非素数下的排列组合,简直凶残 调着调着就过了= = 都不知道怎么过的= = 直接上链接http://hi.baidu.com/aekdycoin/blog/item/147620832b567eb4 ...

  10. BZOJ 1096: [ZJOI2007]仓库建设(动态规划+斜率优化)

    第一次写斜率优化,发现其实也没啥难的,没打过就随便找了一份代码借(chao)鉴(xi)下,不要介意= = 题解实在是懒得写了,贴代码吧= = CODE: #include<cstdio># ...