multi_browser.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. LBPort int //负载均衡 http 端口
  19. httpProxyUrls []string // XrayPool 中的代理信息
  20. socksProxyUrls []string // XrayPool 中的代理信息
  21. }
  22. // NewMultiBrowser 面向与爬虫的时候使用 Browser
  23. func NewMultiBrowser(browserOptions *BrowserOptions) *Browser {
  24. // 从配置中,判断 XrayPool 是否启动
  25. if browserOptions.XrayPoolUrl() == "" {
  26. browserOptions.Log.Panic("XrayPoolUrl is empty")
  27. }
  28. // 尝试从本地的 XrayPoolUrl 获取 代理信息
  29. httpClient, err := my_util.NewHttpClient()
  30. if err != nil {
  31. browserOptions.Log.Panic(errors.New("NewHttpClient error:" + err.Error()))
  32. }
  33. var proxyResult ProxyResult
  34. _, err = httpClient.R().
  35. SetResult(&proxyResult).
  36. Get(httpPrefix +
  37. browserOptions.XrayPoolUrl() +
  38. ":" +
  39. browserOptions.XrayPoolPort() +
  40. "/v1/proxy_list")
  41. if err != nil {
  42. browserOptions.Log.Panic(errors.New("Get error:" + err.Error()))
  43. }
  44. if len(proxyResult.SocksPots) == 0 && len(proxyResult.HttpPots) == 0 {
  45. browserOptions.Log.Panic("XrayPool Not Started!")
  46. }
  47. if len(proxyResult.HttpPots) == 0 {
  48. browserOptions.Log.Panic("HttpPots is empty, need set xray_pool_config.json xray_open_socks_and_http == true")
  49. }
  50. b := &Browser{
  51. log: browserOptions.Log,
  52. rodOptions: browserOptions,
  53. multiBrowser: make([]*rod.Browser, 0),
  54. }
  55. for index, httpPot := range proxyResult.HttpPots {
  56. b.httpProxyUrls = append(b.httpProxyUrls, httpPrefix+browserOptions.XrayPoolUrl()+":"+strconv.Itoa(httpPot))
  57. b.socksProxyUrls = append(b.socksProxyUrls, socksPrefix+browserOptions.XrayPoolUrl()+":"+strconv.Itoa(proxyResult.SocksPots[index]))
  58. }
  59. b.LBPort = proxyResult.LBPort
  60. for i := 0; i < browserOptions.BrowserInstanceCount(); i++ {
  61. lbHttpUrl := fmt.Sprintf(httpPrefix + browserOptions.XrayPoolUrl() + ":" + strconv.Itoa(b.LBPort))
  62. oneBrowser, err := NewBrowserBase(b.log, "", lbHttpUrl, true)
  63. if err != nil {
  64. b.log.Panic(errors.New("NewBrowserBase error:" + err.Error()))
  65. }
  66. b.multiBrowser = append(b.multiBrowser, oneBrowser)
  67. }
  68. return b
  69. }
  70. func (b *Browser) GetOneBrowser() *rod.Browser {
  71. b.browserLocker.Lock()
  72. defer func() {
  73. b.browserIndex++
  74. b.browserLocker.Unlock()
  75. }()
  76. if b.browserIndex >= len(b.multiBrowser) {
  77. b.browserIndex = 0
  78. }
  79. return b.multiBrowser[b.browserIndex]
  80. }
  81. func (b *Browser) Close() {
  82. for _, oneBrowser := range b.multiBrowser {
  83. oneBrowser.Close()
  84. }
  85. }
  86. type ProxyResult struct {
  87. LBPort int `json:"lb_port"`
  88. SocksPots []int `json:"socks_pots"`
  89. HttpPots []int `json:"http_pots"`
  90. }
  91. const (
  92. httpPrefix = "http://"
  93. socksPrefix = "socks5://"
  94. )