check.go 7.4 KB

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