rod_utils.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. package common
  2. import (
  3. "errors"
  4. "git.listensoft.net/tool/jspkit/taxerr"
  5. "github.com/go-kratos/kratos/v2/log"
  6. "github.com/go-rod/rod"
  7. "github.com/go-rod/rod/lib/input"
  8. "github.com/go-rod/rod/lib/utils"
  9. "strings"
  10. "time"
  11. )
  12. func MustHas(page *rod.Page, xpath string) bool {
  13. x, _, _ := HasX(page, xpath)
  14. return x
  15. }
  16. func MustHasX(page *rod.Page, xpath string) bool {
  17. x, _, _ := HasX(page, xpath)
  18. return x
  19. }
  20. func MustHasXV(page *rod.Page, xpath string) bool {
  21. for _, element := range MustElementsX(page, xpath) {
  22. visible, _ := element.Visible()
  23. if visible {
  24. return true
  25. }
  26. }
  27. return false
  28. }
  29. func MustElementX(page *rod.Page, xpath string) *rod.Element {
  30. for i := 0; i < 5; i++ {
  31. x, _ := ElementX(page, xpath)
  32. if x != nil {
  33. return x
  34. }
  35. utils.Sleep(1)
  36. }
  37. return nil
  38. }
  39. func MustHasXV1(page *rod.Page, xpath string) bool {
  40. for _, element := range MustElementsX1(page, xpath) {
  41. visible, _ := element.Visible()
  42. if visible {
  43. return true
  44. }
  45. }
  46. return false
  47. }
  48. func HasX(page *rod.Page, xpath string) (bool, *rod.Element, error) {
  49. var x *rod.Element
  50. var has bool
  51. var err error
  52. err = rod.Try(func() {
  53. has, x, err = page.HasX(xpath)
  54. if has {
  55. return
  56. }
  57. if err != nil {
  58. panic(err)
  59. }
  60. if has {
  61. return
  62. }
  63. iframe := GetAllIframe(page)
  64. for _, pg := range iframe {
  65. has, x, err = pg.HasX(xpath)
  66. if has {
  67. return
  68. }
  69. if err != nil {
  70. panic(err)
  71. }
  72. if has {
  73. return
  74. }
  75. }
  76. })
  77. if x != nil {
  78. x = x.Timeout(time.Second * 15)
  79. }
  80. return has, x, err
  81. }
  82. func ElementX(page *rod.Page, xpath string) (*rod.Element, error) {
  83. _, element, err := HasX(page, xpath)
  84. if err != nil {
  85. err = taxerr.NewWebStuckTitle(false)
  86. }
  87. return element, err
  88. }
  89. func GetAllIframe(page *rod.Page) []*rod.Page {
  90. fs := make([]*rod.Page, 0)
  91. if page.MustHasX(`//iframe`) {
  92. for _, element := range page.MustElementsX(`//iframe`) {
  93. fs = append(fs, element.MustFrame())
  94. fs = append(fs, GetAllIframe(element.MustFrame())...)
  95. }
  96. }
  97. return fs
  98. }
  99. func MustElementXV(page *rod.Page, xpath string) *rod.Element {
  100. for i := 0; i < 5; i++ {
  101. x, _ := ElementsX(page, xpath)
  102. for _, element := range x {
  103. visible, _ := element.Visible()
  104. if visible {
  105. return element
  106. }
  107. }
  108. utils.Sleep(1)
  109. }
  110. return nil
  111. }
  112. func MustElementsX(page *rod.Page, xpath string) (x []*rod.Element) {
  113. for i := 0; i < 5; i++ {
  114. x, _ = ElementsX(page, xpath)
  115. if len(x) != 0 {
  116. break
  117. }
  118. utils.Sleep(1)
  119. }
  120. return x
  121. }
  122. func MustElementsX1(page *rod.Page, xpath string) (x []*rod.Element) {
  123. x, _ = ElementsX(page, xpath)
  124. return x
  125. }
  126. func ElementsX(page *rod.Page, xpath string) ([]*rod.Element, error) {
  127. var arr []*rod.Element
  128. var err error
  129. err = rod.Try(func() {
  130. r, _ := page.Timeout(ClickTimeOut).ElementsX(xpath)
  131. if err != nil {
  132. panic(err)
  133. }
  134. arr = append(arr, r...)
  135. for _, pg := range GetAllIframe(page) {
  136. pg.MustWaitLoad()
  137. r, err = pg.Timeout(ClickTimeOut).ElementsX(xpath)
  138. if err != nil {
  139. panic(err)
  140. }
  141. arr = append(arr, r...)
  142. }
  143. })
  144. return arr, err
  145. }
  146. func WaitElementX(page *rod.Page, xpath string, interval float64) *rod.Element {
  147. for i := 0; i < 60; i++ {
  148. if has, el, _ := HasX(page, xpath); has {
  149. return el
  150. }
  151. time.Sleep(time.Duration(float64(time.Second) * interval))
  152. }
  153. return nil
  154. }
  155. // 有就点 没有就不点击
  156. func MustClick(page *rod.Page, xpath string) {
  157. x := MustElementsX(page, xpath)
  158. for _, element := range x {
  159. visible, _ := element.Visible()
  160. if visible {
  161. element.MustClick()
  162. break
  163. }
  164. }
  165. }
  166. func MustText(page *rod.Page, xpath string) string {
  167. //去掉左右空格
  168. return strings.TrimSpace(MustElementX(page, xpath).MustText())
  169. }
  170. // 输入文字
  171. func Input(p *rod.Page, selector, inputVal string) {
  172. err := rod.Try(func() {
  173. if inputVal == "" || inputVal == "*" {
  174. inputVal = "0"
  175. }
  176. e := rod.Try(func() {
  177. p.Timeout(time.Second).MustSearch(selector).MustSelectAllText().MustFrame().Keyboard.MustType(input.Backspace)
  178. })
  179. if e != nil {
  180. if w := errors.Unwrap(e); w != nil {
  181. log.Info(w.Error() + "-" + selector + "-" + inputVal)
  182. } else {
  183. log.Info(e.Error() + "-" + selector + "-" + inputVal)
  184. }
  185. }
  186. e = rod.Try(func() {
  187. p.Timeout(time.Second).MustSearch(selector).MustSelectAllText().MustInput(inputVal)
  188. })
  189. if e != nil {
  190. if w := errors.Unwrap(e); w != nil {
  191. log.Info(strings.Split(w.Error(), "\t")[0] + "-" + selector + "-" + inputVal)
  192. } else {
  193. log.Info(strings.Split(e.Error(), "\t")[0] + "-" + selector + "-" + inputVal)
  194. }
  195. }
  196. })
  197. if err != nil {
  198. log.Info(err.Error() + "-" + selector + "-" + inputVal)
  199. }
  200. }
  201. // 输入文字
  202. func MustInputX(p *rod.Page, xPath, inputVal string) {
  203. e := MustElementX(p, xPath)
  204. _ = e.ScrollIntoView()
  205. e.MustClick().MustSelectAllText().MustInput(inputVal)
  206. }
  207. // 拦截请求
  208. func PageHijackReq(b *rod.Page, pattern string, ch chan []byte) *rod.HijackRouter {
  209. router := b.HijackRequests()
  210. router.MustAdd(pattern, func(ctx *rod.Hijack) {
  211. rod.Try(func() {
  212. ctx.MustLoadResponse()
  213. ch <- []byte(ctx.Response.Body())
  214. utils.Sleep(5)
  215. select {
  216. case <-ch:
  217. break
  218. }
  219. })
  220. })
  221. go router.Run()
  222. return router
  223. }
  224. // 获取拦截请求的值
  225. func GetHijackResp(ch chan []byte, t float64) ([]byte, error) {
  226. d := time.Duration(t * float64(time.Second))
  227. select {
  228. case val := <-ch:
  229. return val, nil
  230. case <-time.After(d):
  231. return nil, errors.New("请求网页超时,请稍后重试!")
  232. }
  233. }