multi_browser.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package rod_helper
  2. import (
  3. _ "embed"
  4. "errors"
  5. "fmt"
  6. "strconv"
  7. "sync"
  8. "github.com/sirupsen/logrus"
  9. "github.com/allanpk716/ChineseSubFinder/pkg/my_util"
  10. "github.com/go-rod/rod"
  11. )
  12. type Browser struct {
  13. log *logrus.Logger
  14. rodOptions *BrowserOptions // 参数
  15. multiBrowser []*rod.Browser // 多浏览器实例
  16. browserIndex int // 当前使用的浏览器的索引
  17. browserLocker sync.Mutex // 浏览器的锁
  18. LbHttpUrl string // 负载均衡的 http proxy url
  19. LBPort int //负载均衡 http 端口
  20. httpProxyUrls []string // XrayPool 中的代理信息
  21. socksProxyUrls []string // XrayPool 中的代理信息
  22. }
  23. // NewMultiBrowser 面向与爬虫的时候使用 Browser
  24. func NewMultiBrowser(browserOptions *BrowserOptions) *Browser {
  25. // 从配置中,判断 XrayPool 是否启动
  26. if browserOptions.XrayPoolUrl() == "" {
  27. browserOptions.Log.Errorf("XrayPoolUrl is empty")
  28. return nil
  29. }
  30. if browserOptions.XrayPoolPort() == "" {
  31. browserOptions.Log.Errorf("XrayPoolPort is empty")
  32. return nil
  33. }
  34. // 尝试从本地的 XrayPoolUrl 获取 代理信息
  35. httpClient, err := my_util.NewHttpClient()
  36. if err != nil {
  37. browserOptions.Log.Error(errors.New("NewHttpClient error:" + err.Error()))
  38. return nil
  39. }
  40. var proxyResult ProxyResult
  41. _, err = httpClient.R().
  42. SetResult(&proxyResult).
  43. Get(httpPrefix +
  44. browserOptions.XrayPoolUrl() +
  45. ":" +
  46. browserOptions.XrayPoolPort() +
  47. "/v1/proxy_list")
  48. if err != nil {
  49. browserOptions.Log.Error(errors.New("Get error:" + err.Error()))
  50. return nil
  51. }
  52. if proxyResult.Status == "stopped" || (len(proxyResult.SocksPots) == 0 && len(proxyResult.HttpPots) == 0) {
  53. browserOptions.Log.Error("XrayPool Not Started!")
  54. return nil
  55. }
  56. b := &Browser{
  57. log: browserOptions.Log,
  58. rodOptions: browserOptions,
  59. multiBrowser: make([]*rod.Browser, 0),
  60. }
  61. for index, httpPot := range proxyResult.HttpPots {
  62. b.httpProxyUrls = append(b.httpProxyUrls, httpPrefix+browserOptions.XrayPoolUrl()+":"+strconv.Itoa(httpPot))
  63. b.socksProxyUrls = append(b.socksProxyUrls, socksPrefix+browserOptions.XrayPoolUrl()+":"+strconv.Itoa(proxyResult.SocksPots[index]))
  64. }
  65. b.LBPort = proxyResult.LBPort
  66. b.LbHttpUrl = fmt.Sprintf(httpPrefix + browserOptions.XrayPoolUrl() + ":" + strconv.Itoa(b.LBPort))
  67. for i := 0; i < browserOptions.BrowserInstanceCount(); i++ {
  68. oneBrowser, err := NewBrowserBase(b.log, "", b.LbHttpUrl, browserOptions.LoadAdblock)
  69. if err != nil {
  70. b.log.Error(errors.New("NewBrowserBase error:" + err.Error()))
  71. return nil
  72. }
  73. b.multiBrowser = append(b.multiBrowser, oneBrowser)
  74. }
  75. return b
  76. }
  77. func (b *Browser) GetOneBrowser() *rod.Browser {
  78. b.browserLocker.Lock()
  79. defer func() {
  80. b.browserIndex++
  81. b.browserLocker.Unlock()
  82. }()
  83. if b.browserIndex >= len(b.multiBrowser) {
  84. b.browserIndex = 0
  85. }
  86. return b.multiBrowser[b.browserIndex]
  87. }
  88. func (b *Browser) Close() {
  89. for _, oneBrowser := range b.multiBrowser {
  90. oneBrowser.Close()
  91. }
  92. }
  93. type ProxyResult struct {
  94. Status string `json:"status"`
  95. LBPort int `json:"lb_port"`
  96. SocksPots []int `json:"socks_pots"`
  97. HttpPots []int `json:"http_pots"`
  98. }
  99. const (
  100. httpPrefix = "http://"
  101. socksPrefix = "socks5://"
  102. )