check.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package vm
  2. import (
  3. "container/list"
  4. "fmt"
  5. qu "jygit.jydev.jianyu360.cn/data_processing/common_utils"
  6. be "spider_creator/backend"
  7. "time"
  8. "github.com/chromedp/chromedp"
  9. )
  10. // VerifySpiderConfig 验证爬虫配置,支持翻页,列表项数据只提取2条
  11. func (vm *VM) VerifySpiderConfig(sc *be.SpiderConfig) (*be.SpiderConfigVerifyResult, error) {
  12. qu.Debug("sc---", *sc)
  13. verifyResult := list.New()
  14. be.DataResults[sc.Code] = verifyResult
  15. ret := &be.SpiderConfigVerifyResult{false, false, false, false, false, false, false}
  16. _, baseCancelFn, _, _, ctx, incCancelFn := be.NewBrowser(false, false, "") //列表页使用
  17. _, baseCancelFn2, _, _, ctx2, incCancelFn2 := be.NewBrowser(false, false, "") //详情页使用
  18. defer func() {
  19. incCancelFn2()
  20. baseCancelFn2()
  21. incCancelFn()
  22. baseCancelFn()
  23. }()
  24. listRunJs, contentRunJs := sc.ListJSCode, sc.ContentJSCode
  25. //2. 执行JS代码,获取列表页信息
  26. if be.RegSpace.ReplaceAllString(listRunJs, "") == "" {
  27. listRunJs = renderJavascriptCoder(loadListItemsJS, sc)
  28. }
  29. if be.RegSpace.ReplaceAllString(contentRunJs, "") == "" {
  30. contentRunJs = renderJavascriptCoder(loadContentJS, sc)
  31. }
  32. qu.Debug("获取列表页JS代码:", listRunJs)
  33. qu.Debug("获取详情页JS代码:", contentRunJs)
  34. //TODO 3.打开列表,获取条目清单
  35. chromedp.Run(ctx, chromedp.Tasks{
  36. chromedp.Navigate(sc.Href),
  37. chromedp.WaitReady("document.body", chromedp.ByJSPath),
  38. //chromedp.Sleep(1000 * time.Millisecond),
  39. chromedp.Sleep(time.Duration(sc.ListDelayTime) * time.Millisecond),
  40. })
  41. no := 1
  42. T:
  43. for j := 0; j < 2; j++ { //最多检查2页
  44. qu.Debug("开始检查第" + fmt.Sprint(j+1) + "页...")
  45. listResult := make(be.ResultItems, 0)
  46. err := chromedp.Run(ctx, chromedp.Tasks{
  47. chromedp.Evaluate(listRunJs, &listResult),
  48. })
  49. if err != nil {
  50. qu.Debug("执行列表页JS代码失败", err.Error())
  51. continue
  52. }
  53. //TODO 5.操作详情页
  54. qu.Debug("列表采集条数:", len(listResult))
  55. for contentIndex, r := range listResult {
  56. qu.Debug("当前列表页第" + fmt.Sprint(contentIndex+1) + "条")
  57. if contentIndex > 1 { //每页只校验2条
  58. break
  59. }
  60. //打开详情页
  61. err = chromedp.Run(ctx2, chromedp.Tasks{
  62. chromedp.Navigate(r.Href),
  63. chromedp.WaitReady("document.body", chromedp.ByJSPath),
  64. //chromedp.Sleep(2000 * time.Millisecond),
  65. chromedp.Sleep(time.Duration(sc.ContentDelayTime) * time.Millisecond),
  66. })
  67. if err != nil {
  68. qu.Debug("当前列表页第" + fmt.Sprint(contentIndex+1) + "条详情页打开异常")
  69. continue
  70. }
  71. //获取详情页内容
  72. err = chromedp.Run(ctx2, chromedp.Tasks{
  73. chromedp.Evaluate(contentRunJs, r),
  74. })
  75. if err != nil {
  76. qu.Debug("当前列表页第" + fmt.Sprint(contentIndex+1) + "条详情页内容获取失败")
  77. continue
  78. }
  79. //下载附件
  80. if sc.AttachCss != "" {
  81. downloadAttaches(r, vm.attachesDir)
  82. }
  83. r.Site = sc.Site
  84. r.Channel = sc.Channel
  85. if r.Title == "" {
  86. r.Title = r.ListTitle
  87. }
  88. if r.PublishTime == "" {
  89. r.PublishTime = r.ListPubTime
  90. }
  91. r.No = no
  92. no += 1
  93. //结果放入缓存
  94. verifyResult.PushBack(r)
  95. }
  96. qu.Debug("第"+fmt.Sprint(j+1)+"页校验成功数据条数:", verifyResult.Len())
  97. //TODO 6.翻页
  98. if verifyResult.Len() > 0 {
  99. if sc.MaxPages == 1 { //最大页为1,不校验翻页
  100. ret.ListTrunPage = true
  101. break
  102. } else if sc.MaxPages > 1 { //&& !ret.ListTrunPage {
  103. if err = trunPage(sc, sc.ListTurnDelayTime, ctx); err != nil { //翻页失败
  104. qu.Debug("第" + fmt.Sprint(j+1) + "页翻页失败")
  105. break T
  106. } else {
  107. ret.ListTrunPage = true
  108. }
  109. }
  110. }
  111. }
  112. //检查
  113. for el := verifyResult.Front(); el != nil; el = el.Next() {
  114. r, _ := el.Value.(*be.ResultItem)
  115. ret.Title = r.Title != ""
  116. ret.PublishUnit = r.PublishUnit != ""
  117. ret.PublishTime = r.PublishTime != ""
  118. ret.Content = r.Content != ""
  119. ret.Attaches = len(r.AttachLinks) > 0
  120. }
  121. qu.Debug(verifyResult.Len())
  122. ret.ListItems = (sc.MaxPages == 1 && verifyResult.Len() > 0) || (sc.MaxPages > 1 && verifyResult.Len() > 2)
  123. //TODO:每次验证结果存库、内存?
  124. return ret, nil
  125. }
  126. // VerifySpiderConfig 只验证列表标注
  127. //func (vm *VM) VerifySpiderConfig(sc *be.SpiderConfig) (*be.SpiderConfigVerifyResult, error) {
  128. // qu.Debug("sc---", *sc)
  129. // verifyResult := list.New()
  130. // ret := &be.SpiderConfigVerifyResult{false, true, false, true, true, true, false}
  131. // _, baseCancelFn, _, _, ctx, incCancelFn := be.NewBrowser(false, false, "") //列表页使用
  132. // defer func() {
  133. // incCancelFn()
  134. // baseCancelFn()
  135. // }()
  136. //
  137. // listRunJs, contentRunJs := sc.ListJSCode, sc.ContentJSCode
  138. // //TODO 2. 执行JS代码,获取列表页信息
  139. // if be.RegSpace.ReplaceAllString(listRunJs, "") == "" {
  140. // listRunJs = renderJavascriptCoder(loadListItemsJS, sc)
  141. // }
  142. // if be.RegSpace.ReplaceAllString(contentRunJs, "") == "" {
  143. // contentRunJs = renderJavascriptCoder(loadContentJS, sc)
  144. // }
  145. // qu.Debug("列表页JS:", listRunJs)
  146. // //TODO 3.打开列表,获取条目清单
  147. // chromedp.Run(ctx, chromedp.Tasks{
  148. // chromedp.Navigate(sc.Href),
  149. // chromedp.WaitReady("document.body", chromedp.ByJSPath),
  150. // //chromedp.Sleep(1000 * time.Millisecond),
  151. // chromedp.Sleep(time.Duration(sc.ListDelayTime) * time.Millisecond),
  152. // })
  153. // no := 1
  154. //T:
  155. // for j := 0; j < 2; j++ { //最多检查2页
  156. // qu.Debug("开始检查第" + fmt.Sprint(j+1) + "页...")
  157. // listResult := make(be.ResultItems, 0)
  158. // err := chromedp.Run(ctx, chromedp.Tasks{
  159. // chromedp.Evaluate(listRunJs, &listResult),
  160. // })
  161. // if err != nil {
  162. // qu.Debug("执行列表页JS代码失败", err.Error())
  163. // continue
  164. // }
  165. // //TODO 5.操作详情页
  166. // qu.Debug("列表采集条数:", len(listResult))
  167. // for contentIndex, r := range listResult {
  168. // if contentIndex > 1 { //每页只校验2条
  169. // break
  170. // }
  171. // qu.Debug("当前列表页第" + fmt.Sprint(contentIndex+1) + "条")
  172. // r.Site = sc.Site
  173. // r.Channel = sc.Channel
  174. // qu.Debug(r.Title, r.ListTitle)
  175. // if r.Title == "" {
  176. // r.Title = r.ListTitle
  177. // }
  178. // qu.Debug(r.PublishTime, r.ListPubTime)
  179. // if r.PublishTime == "" {
  180. // r.PublishTime = r.ListPubTime
  181. // }
  182. // r.No = no
  183. // no += 1
  184. // //结果放入缓存
  185. // verifyResult.PushBack(r)
  186. // }
  187. // qu.Debug("列表采集条数结果:", verifyResult.Len())
  188. // //TODO 6.翻页
  189. // if verifyResult.Len() > 0 {
  190. // if sc.MaxPages == 1 { //最大页为1,不校验翻页
  191. // ret.ListTrunPage = true
  192. // break
  193. // } else if sc.MaxPages > 1 { // && !ret.ListTrunPage {
  194. // if err = trunPage(sc, sc.ListTurnDelayTime, ctx); err != nil { //翻页失败
  195. // qu.Debug("翻页失败:", err)
  196. // break T
  197. // } else {
  198. // ret.ListTrunPage = true
  199. // }
  200. // }
  201. // }
  202. // }
  203. // //检查
  204. // for el := verifyResult.Front(); el != nil; el = el.Next() {
  205. // r, _ := el.Value.(*be.ResultItem)
  206. // ret.Title = r.Title != ""
  207. // qu.Debug("Check Title:", ret.Title, r.Title, r.ListTitle)
  208. // ret.PublishTime = r.PublishTime != ""
  209. // qu.Debug("Check PublishTime:", ret.PublishTime, r.PublishTime, r.ListPubTime)
  210. // }
  211. // if ret.ListItems {
  212. // ret.ListItems = (sc.MaxPages == 1 && verifyResult.Len() > 0) || (sc.MaxPages > 1 && verifyResult.Len() > 2)
  213. // }
  214. //
  215. // return ret, nil
  216. //}