Hnswszjfwcs_details.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on 2025-04-24
  4. ---------
  5. @summary: 湖南省网上中介服务超市
  6. ---------
  7. @author: lzz
  8. """
  9. import feapder
  10. from items.spider_item import DataBakItem
  11. from untils.attachment import AttachmentDownloader
  12. class Details(feapder.BiddingDetailSpider):
  13. def start_requests(self):
  14. data_list = self.get_tasks_by_rabbitmq(limit=30)
  15. for item in data_list:
  16. # log.debug(item)
  17. request_params = item.get("request_params")
  18. yield feapder.Request(url=item.get("parse_url"), item=item, files_info=item.get("files"),
  19. deal_detail=item.get("deal_detail"),
  20. callback=eval(item.get("parse")), **request_params)
  21. def detail_get(self,request,response):
  22. items = request.item
  23. list_item = DataBakItem(**items)
  24. detail_info = response.json.get('data').get('purchaseNoticeViewVo')
  25. if detail_info.get('isPark') is False:
  26. isPark = "否"
  27. elif detail_info.get('isPark') is True:
  28. isPark = "是"
  29. else:
  30. isPark = "否"
  31. if detail_info.get('isInvestmentProject') is False:
  32. isInvestmentProject = "否"
  33. elif detail_info.get('isInvestmentProject') is False:
  34. isInvestmentProject = "是"
  35. else:
  36. isInvestmentProject = "否"
  37. restrictionsForehead = str(detail_info.get('restrictionsForehead'))
  38. restrictionsForeheadType = detail_info.get('restrictionsForeheadType')
  39. if restrictionsForeheadType == "tallyAmount":
  40. restrictionsForehead = "账上金额(¥" + restrictionsForehead +"元)"
  41. elif restrictionsForeheadType == "totalAssets":
  42. restrictionsForehead = "资产总额(¥" + restrictionsForehead + "元)"
  43. elif restrictionsForeheadType == "squareMeter":
  44. restrictionsForehead = "平方米(" + restrictionsForehead + "平方米)"
  45. elif restrictionsForeheadType == "amountInvested":
  46. restrictionsForehead = "投资额(¥" + restrictionsForehead + "元)"
  47. elif restrictionsForeheadType == "other":
  48. restrictionsForehead = "其他(" + restrictionsForehead + ")"
  49. else:
  50. restrictionsForehead = restrictionsForehead
  51. zjfwjgyq_html = ""
  52. zjfwjgyq = detail_info.get('zjfwjgyq')
  53. if "sfyzzyq" in zjfwjgyq:
  54. zjfwjgyq_html += "资质(资格)要求、"
  55. if "sfybayq" in zjfwjgyq:
  56. zjfwjgyq_html += "备案要求、"
  57. if "sfyryzzzcyq" in zjfwjgyq:
  58. zjfwjgyq_html += "执业(职业)人员要求、"
  59. if "sfjcnfwjk" in zjfwjgyq:
  60. zjfwjgyq_html += "仅承诺服务即可、"
  61. biddingMode = detail_info.get('biddingMode')
  62. if biddingMode == "MONEY":
  63. if not detail_info.get('lowPrice') and detail_info.get('highPrice'):
  64. ServicePrice = " 低于或等于¥" + str(detail_info.get('highPrice')) + "元 "
  65. elif detail_info.get('lowPrice') and detail_info.get('highPrice'):
  66. ServicePrice = " ¥" + str(detail_info.get('lowPrice')) + "元至¥" + str(detail_info.get('highPrice')) + "元 "
  67. else:
  68. ServicePrice = " 高于或等于¥" + str(detail_info.get('lowPrice')) + "元 "
  69. elif biddingMode == "RATE":
  70. if not detail_info.get('lowPrice') and detail_info.get('highPrice'):
  71. ServicePrice = " 低于或等于" + str(detail_info.get('highPrice')) + "%下浮率 "
  72. elif detail_info.get('lowPrice') and detail_info.get('highPrice'):
  73. ServicePrice = str(detail_info.get('lowPrice')) + "至" + str(detail_info.get('highPrice')) + "%下浮率 "
  74. else:
  75. ServicePrice = " 高于或等于" + str(detail_info.get('lowPrice')) + "%下浮率 "
  76. else:
  77. if not detail_info.get('lowPrice') and detail_info.get('highPrice'):
  78. ServicePrice = " ¥" + str(detail_info.get('highPrice')) + "元 "
  79. elif detail_info.get('lowPrice') and detail_info.get('highPrice'):
  80. ServicePrice = " ¥" + str(detail_info.get('lowPrice')) + "元至¥" + str(detail_info.get('highPrice')) + "元 "
  81. else:
  82. ServicePrice = " ¥" + str(detail_info.get('lowPrice')) + "元 "
  83. if detail_info.get('selectTypeName'):
  84. selectTypeName = detail_info.get('selectTypeName')
  85. else:
  86. selectTypeName = detail_info.get('selectModeTypeName')
  87. if detail_info.get('approvalOrgName'):
  88. approvalOrgName = detail_info.get('approvalOrgName')
  89. else:
  90. approvalOrgName = ""
  91. if detail_info.get('publishDate'):
  92. footer_publishDate = detail_info.get('publishDate').split(" ")[0]
  93. else:
  94. footer_publishDate = ""
  95. file_html = "暂无附件"
  96. file_list = detail_info.get('attachmentVoList')
  97. if file_list:
  98. attachments = {}
  99. for f_item in file_list:
  100. temp = f'''
  101. <a class="download-btn">{f_item.get('name')}</a>
  102. '''
  103. file_html = file_html.replace("暂无附件","") + temp
  104. file_name = f_item.get('name')
  105. file_type = f_item.get('fileType').replace(".","")
  106. file_url = f"http://zwfw-new.hunan.gov.cn/hn-zjcs-pub/file/downloadfile/PjAttachment/{f_item.get('attachmentCode')}"
  107. file_types = ['zip','docx','ftp','pdf','doc','rar','gzzb','jpg','png','zbid','xls','xlsx','swp']
  108. if file_type in file_types:
  109. attachment = AttachmentDownloader().fetch_attachment(
  110. file_name=file_name, file_type=file_type, download_url=file_url,
  111. enable_proxy=False)
  112. attachments[str(len(attachments) + 1)] = attachment
  113. if len(attachments) == 0:
  114. pass
  115. else:
  116. list_item.projectinfo = {"attachments": attachments}
  117. html = f'''
  118. <div class="pannel-cont">
  119. <div class="pannel-title">
  120. <div class="pannel-title-name">
  121. 关于为【{detail_info.get('purOrgName')}】公开选取【{detail_info.get('serviceTypeName')}】机构的公告
  122. </div>
  123. <div class="pannel-title-content">
  124. <div class="content-phone">
  125. <span class="info-label">采购发布时间:</span>
  126. <span class="info-value">{detail_info.get('publishDate')}</span>
  127. </div>
  128. <div class="content-addr">
  129. <span class="info-label">报名结束时间:</span>
  130. <span class="info-value">{detail_info.get('signUpEndTime')}</span>
  131. </div>
  132. </div>
  133. </div>
  134. <div >
  135. <div>
  136. <div class="content-info">
  137. <div>
  138. <div>
  139. <div class="content-name">采购项目名称</div>
  140. </div>
  141. <div>
  142. <div class="content-value">{detail_info.get('projectName')}</div>
  143. </div>
  144. </div>
  145. <div>
  146. <div>
  147. <div class="content-name">委托人名称</div>
  148. </div>
  149. <div>
  150. <div class="content-value">{detail_info.get('purOrgName')}</div>
  151. </div>
  152. </div>
  153. <div>
  154. <div>
  155. <div class="content-name">区域性评估采购</div>
  156. </div>
  157. <div>
  158. <div class="content-value">{isPark}</div>
  159. </div>
  160. </div>
  161. <div>
  162. <div>
  163. <div class="content-name">中介事项名称</div>
  164. </div>
  165. <div>
  166. <div class="content-value">{detail_info.get('serviceSubjectName')}</div>
  167. </div>
  168. </div>
  169. <div>
  170. <div>
  171. <div class="content-name">投资审批项目</div>
  172. </div>
  173. <div>
  174. <div class="content-value">{isInvestmentProject}</div>
  175. </div>
  176. </div>
  177. <div>
  178. <div>
  179. <div class="content-name">投资审批项目编码</div>
  180. </div>
  181. <div>
  182. <div class="content-value">{detail_info.get('vcProcessProjectCode')}</div>
  183. </div>
  184. </div>
  185. <div>
  186. <div>
  187. <div class="content-name">采购项目编码</div>
  188. </div>
  189. <div>
  190. <div class="content-value">{detail_info.get('projectCode')}</div>
  191. </div>
  192. </div>
  193. <div>
  194. <div>
  195. <div class="content-name">项目规模</div>
  196. </div>
  197. <div>
  198. <div class="content-value">{restrictionsForehead}</div>
  199. </div>
  200. </div>
  201. <div>
  202. <div>
  203. <div class="content-name">项目规模说明</div>
  204. </div>
  205. <div>
  206. <div class="content-value">
  207. {detail_info.get('restrictionsDescription')}
  208. </div>
  209. </div>
  210. </div>
  211. <div>
  212. <div>
  213. <div class="content-name">服务类型</div>
  214. </div>
  215. <div>
  216. <div class="content-value">{detail_info.get('serviceTypeName')}</div>
  217. </div>
  218. </div>
  219. <div>
  220. <div>
  221. <div class="content-name">服务时限</div>
  222. </div>
  223. <div>
  224. <div class="content-value">{detail_info.get('serviceTimeLimit')}</div>
  225. </div>
  226. </div>
  227. <div>
  228. <div>
  229. <div class="content-name">服务金额</div>
  230. </div>
  231. <div>
  232. <div class="content-value"> {ServicePrice}</div>
  233. </div>
  234. </div>
  235. <div>
  236. <div>
  237. <div class="content-name">金额说明</div>
  238. </div>
  239. <div>
  240. <div class="content-value">{detail_info.get('priceDescription')}</div>
  241. </div>
  242. </div>
  243. <div>
  244. <div>
  245. <div class="content-name">服务内容</div>
  246. </div>
  247. <div>
  248. <div class="content-value">{detail_info.get('servcieContent')}</div>
  249. </div>
  250. </div>
  251. <div>
  252. <div>
  253. <div class="content-name">中介机构要求</div>
  254. </div>
  255. <div>
  256. <div class="content-value">{zjfwjgyq_html}</div>
  257. </div>
  258. </div>
  259. <div>
  260. <div>
  261. <div class="content-name">资质要求</div>
  262. </div>
  263. <div>
  264. <div class="content-value">
  265. {detail_info.get('qualRequire')}
  266. </div>
  267. </div>
  268. </div>
  269. <div>
  270. <div>
  271. <div class="content-name">备案要求说明</div>
  272. </div>
  273. <div>
  274. <div class="content-value">{detail_info.get('bayqsm')}</div>
  275. </div>
  276. </div>
  277. <div>
  278. <div>
  279. <div class="content-name">其他要求说明</div>
  280. </div>
  281. <div>
  282. <div class="content-value">
  283. {detail_info.get('otherRequirements')}
  284. </div>
  285. </div>
  286. </div>
  287. <div>
  288. <div>
  289. <div class="content-name">选取中介方式</div>
  290. </div>
  291. <div>
  292. <div class="content-value">
  293. {selectTypeName}
  294. </div>
  295. </div>
  296. </div>
  297. <div>
  298. <div>
  299. <div class="content-name">截止报名时间</div>
  300. </div>
  301. <div>
  302. <div class="content-value">{detail_info.get('signUpEndTime')}</div>
  303. </div>
  304. </div>
  305. <div>
  306. <div>
  307. <div class="content-name">公开选取中介时间</div>
  308. </div>
  309. <div>
  310. <div class="content-value">{detail_info.get('selectTime')}</div>
  311. </div>
  312. </div>
  313. <div>
  314. <div>
  315. <div class="content-name">咨询电话</div>
  316. </div>
  317. <div>
  318. <div class="content-value">{detail_info.get('consultPhone')}</div>
  319. </div>
  320. </div>
  321. <div>
  322. <div>
  323. <div class="content-name">监督电话</div>
  324. </div>
  325. <div>
  326. <div class="content-value">{detail_info.get('complaintsHotline')}</div>
  327. </div>
  328. </div>
  329. <div>
  330. <div>
  331. <div class="content-name">备注</div>
  332. </div>
  333. <div>
  334. <div class="content-value">
  335. {detail_info.get('note')}
  336. </div>
  337. </div>
  338. </div>
  339. <div>
  340. <div>
  341. <div class="content-name">附件下载</div>
  342. </div>
  343. <div>
  344. <div class="content-value">
  345. <div>
  346. {file_html}
  347. </div>
  348. </div>
  349. </div>
  350. </div>
  351. <div>
  352. <div class="el-col el-col-24" style="padding-left: 10px; padding-right: 10px;">
  353. <div class="content-value" style="text-align: right;">{approvalOrgName}</div>
  354. </div>
  355. <div class="el-col el-col-24" style="padding-left: 10px; padding-right: 10px;">
  356. <div class="content-value" style="text-align: right;">{footer_publishDate}</div>
  357. </div>
  358. </div>
  359. </div>
  360. </div>
  361. </div>
  362. </div>
  363. '''
  364. list_item.contenthtml = html.replace("None","无")
  365. yield list_item
  366. if __name__ == "__main__":
  367. Details(redis_key="lzz:Hnswszjfwcs").start()