|
@@ -0,0 +1,959 @@
|
|
|
+package lxrod
|
|
|
+
|
|
|
+import (
|
|
|
+ "context"
|
|
|
+ "encoding/base64"
|
|
|
+ "fmt"
|
|
|
+ "git.listensoft.net/tool/jspkit/common/lxhttp"
|
|
|
+ "git.listensoft.net/tool/jspkit/common/variable"
|
|
|
+ "git.listensoft.net/tool/jspkit/taxerr"
|
|
|
+ "github.com/go-rod/stealth"
|
|
|
+ "io"
|
|
|
+ "net/http"
|
|
|
+ "net/url"
|
|
|
+ "os"
|
|
|
+ "os/exec"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/go-rod/rod"
|
|
|
+ "github.com/go-rod/rod/lib/launcher"
|
|
|
+ "github.com/go-rod/rod/lib/proto"
|
|
|
+ "github.com/go-rod/rod/lib/utils"
|
|
|
+)
|
|
|
+
|
|
|
+var (
|
|
|
+ LastAlertMsg = make(chan string, 100)
|
|
|
+)
|
|
|
+
|
|
|
+// 只允许task.go 初始化一次
|
|
|
+type Lxrod struct {
|
|
|
+ Area variable.Area
|
|
|
+ Browser *rod.Browser
|
|
|
+ Launcher *launcher.Launcher
|
|
|
+ NoByPass bool //添加反反爬虫代码 原理就是执行一段js去掉window属性中关于自动化的代码
|
|
|
+ Headless bool //headless 默认显示浏览器 为true是不显示浏览器
|
|
|
+ MonitorDialog bool //默认监控alert然后去点击true 如果要自己处理 设置为true不添加监控
|
|
|
+ PageEvent bool //默认每个页面的监听事件 设置为true不添加监控
|
|
|
+ UseProxy bool //代理
|
|
|
+ Leakless bool
|
|
|
+ NoDefaultDevice bool
|
|
|
+ Proxy string
|
|
|
+ ProxyAuth string
|
|
|
+ WsURL string // rod的ws地址
|
|
|
+ NoEachEventForCreated bool
|
|
|
+ LoginErrImg string
|
|
|
+}
|
|
|
+
|
|
|
+// 关闭浏览器 统一控制
|
|
|
+func (lr *Lxrod) CloseBrowser() (err error) {
|
|
|
+ if lr.Browser != nil {
|
|
|
+ return rod.Try(func() {
|
|
|
+ if lr.Browser != nil {
|
|
|
+ lr.Browser.Close()
|
|
|
+ go rod.Try(func() {
|
|
|
+
|
|
|
+ lr.Launcher.Cleanup()
|
|
|
+ lr.Launcher.Kill()
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// 关闭浏览器 统一控制
|
|
|
+func (lr *Lxrod) CloseBrowserNew() {
|
|
|
+ if lr.Browser != nil {
|
|
|
+ _ = lr.Browser.Close()
|
|
|
+
|
|
|
+ lr.Launcher.Cleanup()
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func GetAlertMsg() string {
|
|
|
+
|
|
|
+ select {
|
|
|
+ case v := <-LastAlertMsg:
|
|
|
+
|
|
|
+ return v
|
|
|
+ case <-time.After(time.Second * 8):
|
|
|
+
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func ClickDialog(p *rod.Page, h func(bool, string)) { //默认添加点击alert事件
|
|
|
+ go func() {
|
|
|
+ defer func() {
|
|
|
+ if err := recover(); err != nil {
|
|
|
+
|
|
|
+ rod.Try(func() { h(true, "确定") })
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ h(true, "确定") //dialog 浏览器语言中文默认是确定 alert浏览器语言英文默认是ok
|
|
|
+ }()
|
|
|
+}
|
|
|
+
|
|
|
+// 监听 alert confirm 等事件打开
|
|
|
+func DialogWatch(ctx context.Context, page *rod.Page) {
|
|
|
+
|
|
|
+ defer func() {
|
|
|
+ if r := recover(); r != nil {
|
|
|
+
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ _, h := page.MustHandleDialog()
|
|
|
+ go page.EachEvent(func(e *proto.PageJavascriptDialogOpening) {
|
|
|
+ defer func() {
|
|
|
+
|
|
|
+ if r := recover(); r != nil {
|
|
|
+
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ if strings.Contains(page.MustInfo().URL, `henan`) {
|
|
|
+ if strings.Contains(e.Message, `请重新登录`) || strings.Contains(e.Message, `访问异常`) {
|
|
|
+ page.Browser().MustSetCookies()
|
|
|
+
|
|
|
+ page.MustNavigate("")
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if strings.Contains(page.MustInfo().URL, `jiangxi`) {
|
|
|
+ if strings.Contains(e.Message, "纳税人识别号未注册电子税务局") {
|
|
|
+
|
|
|
+ //LastAlertMsgJiangXi <- e.Message
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ LastAlertMsg <- e.Message
|
|
|
+
|
|
|
+ ClickDialog(page, h)
|
|
|
+ utils.Sleep(5)
|
|
|
+ if len(LastAlertMsg) > 0 {
|
|
|
+ _ = <-LastAlertMsg
|
|
|
+ } else {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ })()
|
|
|
+}
|
|
|
+
|
|
|
+// 新建浏览器对象-青岛
|
|
|
+func (lxrod *Lxrod) Newqd(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+ utils.Sleep(1)
|
|
|
+ lxrod.Launcher = launcher.New()
|
|
|
+ lxrod.Launcher.Set("window-size", "1600,900").
|
|
|
+ Set("no-sandbox").
|
|
|
+ Set("ignore-certificate-errors").
|
|
|
+ Set("ignore-certificate-errors-spki-list").
|
|
|
+ Set("ignore-ssl-errors").
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ Headless(lxrod.Headless)
|
|
|
+ //lxrod.Launcher.UserDataDir("user-data")
|
|
|
+ //if viper.GetString("env") == string(variable.Development) {
|
|
|
+ // lxrod.Launcher.Leakless(false) //开发环境不使用用leakless
|
|
|
+ //}
|
|
|
+ lxrod.Launcher.Flags["disable-blink-features"] = []string{"AutomationControlled"}
|
|
|
+ u, err := lxrod.Launcher.Launch()
|
|
|
+ if err != nil {
|
|
|
+
|
|
|
+ err = taxerr.New("调用浏览器失败,请稍后重试!")
|
|
|
+ return lxrod.Browser, p, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ b = rod.New().ControlURL(u).MustConnect().Context(ctx).NoDefaultDevice() //.Trace(true) Trace调试打开
|
|
|
+ utils.Sleep(1)
|
|
|
+ b.MustSetCookies()
|
|
|
+ p = b.MustPage("").MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ lxrod.Browser = b
|
|
|
+ return lxrod.Browser, p, err
|
|
|
+}
|
|
|
+
|
|
|
+// 新建浏览器对象
|
|
|
+func (lxrod *Lxrod) New(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+ utils.Sleep(1)
|
|
|
+ // if viper.GetString("env") == string(variable.Development) { //直接启动浏览器
|
|
|
+ lxrod.Launcher = launcher.New()
|
|
|
+ // } else { //容器内启动
|
|
|
+ // serviceURL := os.Getenv("serviceURL")
|
|
|
+ // lxrod.Launcher, err = launcher.NewManaged(serviceURL)
|
|
|
+ // if err != nil {
|
|
|
+ //
|
|
|
+ // err = taxerr.New("调用浏览器失败,请稍后重试!")
|
|
|
+ // return lxrod.Browser, p, err
|
|
|
+ // }
|
|
|
+ // lxrod.Launcher.XVFB("--server-num=5", "--server-args=-screen 0 1600x900x16")
|
|
|
+ // }
|
|
|
+ lxrod.Launcher.Set("window-size", "1600,900").
|
|
|
+ Set("no-sandbox").
|
|
|
+ Set("ignore-certificate-errors").
|
|
|
+ Set("ignore-certificate-errors-spki-list").
|
|
|
+ Set("ignore-ssl-errors").
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ //UserDataDir("user-data").
|
|
|
+ Headless(lxrod.Headless)
|
|
|
+ //if lxrod.Area == "hebei" {
|
|
|
+ // lxrod.Launcher.UserDataDir("user-data")
|
|
|
+ //}
|
|
|
+ //if lxrod.Area == "hebei" {
|
|
|
+ lxrod.Launcher.Flags["disable-blink-features"] = []string{"AutomationControlled"}
|
|
|
+ //}
|
|
|
+ //if viper.GetString("env") == string(variable.Development) {
|
|
|
+ // //lxrod.Launcher.Leakless(false) //开发环境不使用用leakless todo 进程老是结束不掉
|
|
|
+ //}
|
|
|
+ // Leakless(lxrod.Leakless)
|
|
|
+ // chromePath, ok := launcher.LookPath()
|
|
|
+ // fmt.Println(ok)
|
|
|
+ // fmt.Println(chromePath)
|
|
|
+ // if ok {
|
|
|
+ // lxrod.Launcher.Bin(chromePath)
|
|
|
+ // }
|
|
|
+ if lxrod.UseProxy {
|
|
|
+ lxrod.Proxy, lxrod.ProxyAuth = GetLocalProxy(string(lxrod.Area))
|
|
|
+ lxrod.Launcher.Proxy(lxrod.Proxy)
|
|
|
+ }
|
|
|
+ u, err := lxrod.Launcher.Launch()
|
|
|
+ lxrod.WsURL = u
|
|
|
+ if err != nil {
|
|
|
+ err = taxerr.New("调用浏览器失败,请稍后重试!")
|
|
|
+ return lxrod.Browser, p, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ // lxrod.Browser = rod.New().Client(lxrod.Launcher.MustClient()).MustConnect().Context(ctx).MustSetCookies() //.Trace(true) Trace调试打开
|
|
|
+ lxrod.Browser = rod.New().ControlURL(u).MustConnect().Context(ctx) //.Trace(true) Trace调试打开
|
|
|
+ utils.Sleep(1)
|
|
|
+ lxrod.Browser.MustSetCookies()
|
|
|
+ if lxrod.NoDefaultDevice {
|
|
|
+ lxrod.Browser.NoDefaultDevice()
|
|
|
+ }
|
|
|
+ if !lxrod.NoByPass {
|
|
|
+ //是否需要反反爬虫
|
|
|
+ p = stealth.MustPage(lxrod.Browser)
|
|
|
+ } else {
|
|
|
+ p, err = lxrod.Browser.Page(proto.TargetCreateTarget{})
|
|
|
+ if err != nil {
|
|
|
+ return lxrod.Browser, p, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // launcher.Open(lxrod.Browser.ServeMonitor(""))
|
|
|
+ p.MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ if lxrod.MonitorDialog {
|
|
|
+ DialogWatch(ctx, p) //为新打开的页面添加一个dialog监控
|
|
|
+ }
|
|
|
+ if !lxrod.PageEvent {
|
|
|
+ lxrod.EachPageCreatedEvent(ctx, lxrod.Browser)
|
|
|
+ }
|
|
|
+ return lxrod.Browser, p, err
|
|
|
+}
|
|
|
+
|
|
|
+func (lxrod *Lxrod) NewSd(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+ utils.Sleep(1)
|
|
|
+ // if viper.GetString("env") == string(variable.Development) { //直接启动浏览器
|
|
|
+ lxrod.Launcher = launcher.New()
|
|
|
+ // } else { //容器内启动
|
|
|
+ // serviceURL := os.Getenv("serviceURL")
|
|
|
+ // lxrod.Launcher, err = launcher.NewManaged(serviceURL)
|
|
|
+ // if err != nil {
|
|
|
+ //
|
|
|
+ // err = taxerr.New("调用浏览器失败,请稍后重试!")
|
|
|
+ // return lxrod.Browser, p, err
|
|
|
+ // }
|
|
|
+ // lxrod.Launcher.XVFB("--server-num=5", "--server-args=-screen 0 1600x900x16")
|
|
|
+ // }
|
|
|
+ lxrod.Launcher.Set("window-size", "1600,900").
|
|
|
+ Set("no-sandbox").
|
|
|
+ Set("ignore-certificate-errors").
|
|
|
+ Set("ignore-certificate-errors-spki-list").
|
|
|
+ Set("ignore-ssl-errors").
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ //UserDataDir("user-data").
|
|
|
+ Headless(lxrod.Headless)
|
|
|
+ //if viper.GetString("env") == string(variable.Development) {
|
|
|
+ // lxrod.Launcher.Leakless(false) //开发环境不使用用leakless
|
|
|
+ //}
|
|
|
+ // Leakless(lxrod.Leakless)
|
|
|
+ // chromePath, ok := launcher.LookPath()
|
|
|
+ // fmt.Println(ok)
|
|
|
+ // fmt.Println(chromePath)
|
|
|
+ // if ok {
|
|
|
+ // lxrod.Launcher.Bin(chromePath)
|
|
|
+ // }
|
|
|
+ if lxrod.UseProxy {
|
|
|
+ lxrod.Proxy, lxrod.ProxyAuth = GetLocalProxy(string(lxrod.Area))
|
|
|
+ lxrod.Launcher.Proxy(lxrod.Proxy)
|
|
|
+ }
|
|
|
+ u, err := lxrod.Launcher.Launch()
|
|
|
+ if err != nil {
|
|
|
+
|
|
|
+ err = taxerr.New("调用浏览器失败,请稍后重试!")
|
|
|
+ return lxrod.Browser, p, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ // lxrod.Browser = rod.New().Client(lxrod.Launcher.MustClient()).MustConnect().Context(ctx).MustSetCookies() //.Trace(true) Trace调试打开
|
|
|
+ lxrod.Browser = rod.New().ControlURL(u).MustConnect().Context(ctx) //.Trace(true) Trace调试打开
|
|
|
+ utils.Sleep(1)
|
|
|
+ lxrod.Browser.MustSetCookies()
|
|
|
+ if lxrod.NoDefaultDevice {
|
|
|
+ lxrod.Browser.NoDefaultDevice()
|
|
|
+ }
|
|
|
+ if !lxrod.NoByPass {
|
|
|
+ //是否需要反反爬虫
|
|
|
+ p = stealth.MustPage(lxrod.Browser)
|
|
|
+ } else {
|
|
|
+ p, err = lxrod.Browser.Page(proto.TargetCreateTarget{})
|
|
|
+ if err != nil {
|
|
|
+ return lxrod.Browser, p, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // launcher.Open(lxrod.Browser.ServeMonitor(""))
|
|
|
+ p.MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ if lxrod.MonitorDialog {
|
|
|
+ DialogWatch(ctx, p) //为新打开的页面添加一个dialog监控
|
|
|
+ }
|
|
|
+ lxrod.EachPageCreatedEvent(ctx, lxrod.Browser)
|
|
|
+ return lxrod.Browser, p, err
|
|
|
+}
|
|
|
+
|
|
|
+// 新建浏览器对象 易代账移除EachPageCreatedEvent否则新标签页打不开 by fengxianwei
|
|
|
+func (lxrod *Lxrod) NewByydz(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+ utils.Sleep(1)
|
|
|
+ // if viper.GetString("env") == string(variable.Development) { //直接启动浏览器
|
|
|
+ lxrod.Launcher = launcher.New()
|
|
|
+ // } else { //容器内启动
|
|
|
+ // serviceURL := os.Getenv("serviceURL")
|
|
|
+ // lxrod.Launcher, err = launcher.NewManaged(serviceURL)
|
|
|
+ // if err != nil {
|
|
|
+ //
|
|
|
+ // err = taxerr.New("调用浏览器失败,请稍后重试!")
|
|
|
+ // return lxrod.Browser, p, err
|
|
|
+ // }
|
|
|
+ // lxrod.Launcher.XVFB("--server-num=5", "--server-args=-screen 0 1600x900x16")
|
|
|
+ // }
|
|
|
+ lxrod.Launcher.Set("window-size", "1600,900").
|
|
|
+ Set("no-sandbox").
|
|
|
+ Set("ignore-certificate-errors").
|
|
|
+ Set("ignore-certificate-errors-spki-list").
|
|
|
+ Set("ignore-ssl-errors").
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ //UserDataDir("user-data").
|
|
|
+ Headless(lxrod.Headless)
|
|
|
+ //if viper.GetString("env") == string(variable.Development) {
|
|
|
+ // lxrod.Launcher.Leakless(false) //开发环境不使用用leakless
|
|
|
+ //}
|
|
|
+ if lxrod.UseProxy {
|
|
|
+ lxrod.Proxy, lxrod.ProxyAuth = GetLocalProxy(string(lxrod.Area))
|
|
|
+ lxrod.Launcher.Proxy(lxrod.Proxy)
|
|
|
+ }
|
|
|
+ u, err := lxrod.Launcher.Launch()
|
|
|
+ if err != nil {
|
|
|
+
|
|
|
+ err = taxerr.New("调用浏览器失败,请稍后重试!")
|
|
|
+ return lxrod.Browser, p, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ lxrod.Browser = rod.New().ControlURL(u).MustConnect().Context(ctx) //.Trace(true) Trace调试打开
|
|
|
+ utils.Sleep(1)
|
|
|
+ lxrod.Browser.MustSetCookies()
|
|
|
+ if lxrod.NoDefaultDevice {
|
|
|
+ lxrod.Browser.NoDefaultDevice()
|
|
|
+ }
|
|
|
+ if !lxrod.NoByPass {
|
|
|
+ //是否需要反反爬虫
|
|
|
+ p = stealth.MustPage(lxrod.Browser)
|
|
|
+ } else {
|
|
|
+ p, err = lxrod.Browser.Page(proto.TargetCreateTarget{})
|
|
|
+ if err != nil {
|
|
|
+ return lxrod.Browser, p, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ p.MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ if lxrod.MonitorDialog {
|
|
|
+ DialogWatch(ctx, p) //为新打开的页面添加一个dialog监控
|
|
|
+ }
|
|
|
+ return lxrod.Browser, p, err
|
|
|
+}
|
|
|
+
|
|
|
+// 跳过反爬虫检查
|
|
|
+func (lxrod *Lxrod) EachPageCreatedEvent(ctx context.Context, browser *rod.Browser) {
|
|
|
+ if !lxrod.MonitorDialog && lxrod.NoByPass {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ go browser.EachEvent(func(e *proto.TargetTargetCreated) {
|
|
|
+ defer func() {
|
|
|
+ if r := recover(); r != nil {
|
|
|
+
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ if e.TargetInfo.Type != proto.TargetTargetInfoTypePage {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page := browser.MustPageFromTargetID(e.TargetInfo.TargetID)
|
|
|
+ if !lxrod.NoByPass {
|
|
|
+ _, err := page.EvalOnNewDocument(stealth.JS)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page.MustEvalOnNewDocument(stealth.JS)
|
|
|
+ page.MustSetUserAgent(nil)
|
|
|
+ utils.E(proto.RuntimeRunIfWaitingForDebugger{}.Call(page))
|
|
|
+ }
|
|
|
+ page.MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ if lxrod.MonitorDialog {
|
|
|
+ DialogWatch(ctx, page) //为新打开的页面添加一个dialog监控
|
|
|
+ }
|
|
|
+ })()
|
|
|
+ utils.E(proto.TargetSetAutoAttach{
|
|
|
+ AutoAttach: true,
|
|
|
+ WaitForDebuggerOnStart: true,
|
|
|
+ Flatten: true,
|
|
|
+ }.Call(browser))
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func PageToClient(page *rod.Page, BaseURL string) (*http.Client, error) {
|
|
|
+ c := lxhttp.NewHttpClient()
|
|
|
+ e := rod.Try(func() {
|
|
|
+ cookies := page.MustCookies()
|
|
|
+ var cookiesArr []*http.Cookie
|
|
|
+ for _, v := range cookies {
|
|
|
+ var cookie http.Cookie
|
|
|
+ cookie.Name = v.Name
|
|
|
+ cookie.Value = v.Value
|
|
|
+ cookiesArr = append(cookiesArr, &cookie)
|
|
|
+ }
|
|
|
+ clientURL, _ := url.Parse(BaseURL)
|
|
|
+ c.Jar.SetCookies(clientURL, cookiesArr)
|
|
|
+ })
|
|
|
+ return c, e
|
|
|
+}
|
|
|
+
|
|
|
+func BrowserToClient(b *rod.Browser, BaseURL string) (*http.Client, error) {
|
|
|
+ domainMap := map[string][]*http.Cookie{}
|
|
|
+ c := lxhttp.NewHttpClient()
|
|
|
+ e := rod.Try(func() {
|
|
|
+ cookies := b.MustGetCookies()
|
|
|
+ for _, v := range cookies {
|
|
|
+ var cookie http.Cookie
|
|
|
+ cookie.Name = v.Name
|
|
|
+ cookie.Value = v.Value
|
|
|
+ cookie.Path = v.Path
|
|
|
+ cookie.Domain = v.Domain
|
|
|
+ domainMap[v.Domain] = append(domainMap[v.Domain], &cookie)
|
|
|
+ }
|
|
|
+ for _, cookie := range domainMap {
|
|
|
+ clientURL, _ := url.Parse(BaseURL)
|
|
|
+ c.Jar.SetCookies(clientURL, cookie)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return c, e
|
|
|
+}
|
|
|
+
|
|
|
+func BrowserToClientYunnan(b *rod.Browser, BaseURL string) (*http.Client, error) {
|
|
|
+ domainMap := map[string][]*http.Cookie{}
|
|
|
+ c := lxhttp.NewHttpClient()
|
|
|
+ e := rod.Try(func() {
|
|
|
+ cookies := b.MustGetCookies()
|
|
|
+ for _, v := range cookies {
|
|
|
+ var cookie http.Cookie
|
|
|
+ cookie.Name = v.Name
|
|
|
+ cookie.Value = v.Value
|
|
|
+ cookie.Path = v.Path
|
|
|
+ cookie.Domain = v.Domain
|
|
|
+ domainMap[v.Domain] = append(domainMap[v.Domain], &cookie)
|
|
|
+ }
|
|
|
+ for _, cookie := range domainMap {
|
|
|
+ clientURL, _ := url.Parse(BaseURL)
|
|
|
+ c.Jar.SetCookies(clientURL, cookie)
|
|
|
+ }
|
|
|
+ u, auth := GetLocalProxy("yunnan")
|
|
|
+ uu, _ := url.Parse(u)
|
|
|
+ c.Transport = &http.Transport{Proxy: http.ProxyURL(uu), ProxyConnectHeader: http.Header{
|
|
|
+ "Proxy-Authorization": []string{"Basic " + base64.StdEncoding.EncodeToString([]byte(auth))},
|
|
|
+ }}
|
|
|
+ })
|
|
|
+ return c, e
|
|
|
+}
|
|
|
+
|
|
|
+func BrowserToClientByProxy(b *rod.Browser, BaseURL string) (*http.Client, error) {
|
|
|
+ area := ""
|
|
|
+ {
|
|
|
+ u, _ := url.Parse(BaseURL)
|
|
|
+ area = strings.Split(u.Host, ".")[1]
|
|
|
+ }
|
|
|
+ if area == "" {
|
|
|
+ return lxhttp.NewHttpClient(), taxerr.TimeOut
|
|
|
+ }
|
|
|
+ domainMap := map[string][]*http.Cookie{}
|
|
|
+ c := lxhttp.NewHttpClient()
|
|
|
+ proxy, auth := GetLocalProxy(area)
|
|
|
+ uu, _ := url.Parse(proxy)
|
|
|
+ tr := &http.Transport{Proxy: http.ProxyURL(uu)}
|
|
|
+ if auth != "" {
|
|
|
+ tr.ProxyConnectHeader = http.Header{
|
|
|
+ "Proxy-Authorization": []string{"Basic " + base64.StdEncoding.EncodeToString([]byte(auth))},
|
|
|
+ }
|
|
|
+ }
|
|
|
+ c.Transport = tr
|
|
|
+ e := rod.Try(func() {
|
|
|
+ cookies := b.MustGetCookies()
|
|
|
+ for _, v := range cookies {
|
|
|
+ var cookie http.Cookie
|
|
|
+ cookie.Name = v.Name
|
|
|
+ cookie.Value = v.Value
|
|
|
+ cookie.Path = v.Path
|
|
|
+ cookie.Domain = v.Domain
|
|
|
+ domainMap[v.Domain] = append(domainMap[v.Domain], &cookie)
|
|
|
+ }
|
|
|
+ for _, cookie := range domainMap {
|
|
|
+ clientURL, _ := url.Parse(BaseURL)
|
|
|
+ c.Jar.SetCookies(clientURL, cookie)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return c, e
|
|
|
+}
|
|
|
+
|
|
|
+func (lxrod *Lxrod) NewByHjj(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ _ = rod.Try(func() {
|
|
|
+ _ = lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+ lxrod.Launcher = launcher.New()
|
|
|
+ lxrod.Launcher.Set("window-size", "1600,900").
|
|
|
+ Set("no-sandbox").
|
|
|
+ Set("ignore-certificate-errors").
|
|
|
+ Set("ignore-certificate-errors-spki-list").
|
|
|
+ Set("ignore-ssl-errors").
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ Headless(lxrod.Headless)
|
|
|
+ //lxrod.Launcher.UserDataDir("user-data")
|
|
|
+ lxrod.Launcher.Flags["disable-blink-features"] = []string{"AutomationControlled"}
|
|
|
+ u, err := lxrod.Launcher.Launch()
|
|
|
+ if err != nil {
|
|
|
+
|
|
|
+ err = taxerr.New("调用浏览器失败,请稍后重试!")
|
|
|
+ return lxrod.Browser, p, err
|
|
|
+ }
|
|
|
+ err = rod.Try(func() {
|
|
|
+ lxrod.Browser = rod.New().ControlURL(u).MustConnect().Context(ctx)
|
|
|
+ utils.Sleep(1)
|
|
|
+ lxrod.Browser.MustSetCookies()
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return nil, nil, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ lxrod.Browser.NoDefaultDevice()
|
|
|
+ p = stealth.MustPage(lxrod.Browser)
|
|
|
+ if lxrod.MonitorDialog {
|
|
|
+ //为新打开的页面添加一个dialog监控
|
|
|
+ DialogWatch(ctx, p)
|
|
|
+ go lxrod.Browser.EachEvent(func(e *proto.TargetTargetCreated) {
|
|
|
+ defer func() {
|
|
|
+ if r := recover(); r != nil {
|
|
|
+
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ if e.TargetInfo.Type != proto.TargetTargetInfoTypePage {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page := lxrod.Browser.MustPageFromTargetID(e.TargetInfo.TargetID)
|
|
|
+ DialogWatch(ctx, page)
|
|
|
+ })()
|
|
|
+ }
|
|
|
+ p = p.MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ return lxrod.Browser, p, err
|
|
|
+}
|
|
|
+
|
|
|
+// 新建浏览器对象
|
|
|
+func (lxrod *Lxrod) NewBeijing(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ os.RemoveAll("tmp/")
|
|
|
+ })
|
|
|
+
|
|
|
+ lxrod.Launcher = launcher.NewUserMode()
|
|
|
+ u, err := lxrod.Launcher.
|
|
|
+ // New().
|
|
|
+ Leakless(true).
|
|
|
+ UserDataDir("tmp/t").
|
|
|
+ Set("disable-default-apps").
|
|
|
+ Set("no-first-run").
|
|
|
+ //Set("disable-plugins").
|
|
|
+ Set("disable-popup-blocking").
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ Headless(lxrod.Headless).
|
|
|
+ Launch()
|
|
|
+ if err != nil {
|
|
|
+
|
|
|
+ return nil, nil, taxerr.NewUser("浏览器创建失败请稍后重试1")
|
|
|
+ }
|
|
|
+
|
|
|
+ utils.Sleep(3)
|
|
|
+
|
|
|
+ err = rod.Try(func() {
|
|
|
+ b = rod.New().ControlURL(u).Timeout(time.Second * 60).MustConnect().Context(ctx).NoDefaultDevice()
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+
|
|
|
+ return nil, nil, taxerr.NewUser("浏览器创建失败请稍后重试2")
|
|
|
+ }
|
|
|
+
|
|
|
+ b.MustIncognito()
|
|
|
+ p = b.MustPage("")
|
|
|
+ lxrod.Browser = b
|
|
|
+ go b.EachEvent(func(e *proto.TargetTargetCreated) {
|
|
|
+ defer func() {
|
|
|
+ if r := recover(); r != nil {
|
|
|
+
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ if e.TargetInfo.Type != proto.TargetTargetInfoTypePage {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page := b.MustPageFromTargetID(e.TargetInfo.TargetID)
|
|
|
+ page.MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ })()
|
|
|
+ return b, p, err
|
|
|
+}
|
|
|
+
|
|
|
+func (lxrod *Lxrod) NewHuBei(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+ l := launcher.
|
|
|
+ New().
|
|
|
+ Set("window-size", "1600,900").
|
|
|
+ Leakless(true).
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ Headless(false)
|
|
|
+ lxrod.Launcher = l
|
|
|
+ //lxrod.Launcher.UserDataDir("user-data")
|
|
|
+ l.Flags["disable-blink-features"] = []string{"AutomationControlled"}
|
|
|
+ //if viper.GetString("env") == string(variable.Development) {
|
|
|
+ // l.Leakless(false) //开发环境不使用用leakless
|
|
|
+ //}
|
|
|
+ u := l.MustLaunch()
|
|
|
+
|
|
|
+ b = rod.New().ControlURL(u).MustConnect().NoDefaultDevice()
|
|
|
+ p = stealth.MustPage(b)
|
|
|
+ lxrod.Browser = b
|
|
|
+ go b.EachEvent(func(e *proto.TargetTargetCreated) {
|
|
|
+ defer func() {
|
|
|
+ if r := recover(); r != nil {
|
|
|
+
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ if e.TargetInfo.Type != proto.TargetTargetInfoTypePage {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page := b.MustPageFromTargetID(e.TargetInfo.TargetID)
|
|
|
+
|
|
|
+ _, err := page.EvalOnNewDocument(stealth.JS)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page.MustEvalOnNewDocument(stealth.JS)
|
|
|
+ page.MustSetUserAgent(nil)
|
|
|
+ utils.E(proto.RuntimeRunIfWaitingForDebugger{}.Call(page))
|
|
|
+ page.MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ })()
|
|
|
+ utils.E(proto.TargetSetAutoAttach{
|
|
|
+ AutoAttach: true,
|
|
|
+ WaitForDebuggerOnStart: true,
|
|
|
+ Flatten: true,
|
|
|
+ }.Call(b))
|
|
|
+ return b, p, err
|
|
|
+}
|
|
|
+func (lxrod *Lxrod) NewNoParam() (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+ l := launcher.
|
|
|
+ New().
|
|
|
+ Set("window-size", "1600,900").
|
|
|
+ Leakless(true).
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ Headless(false)
|
|
|
+ lxrod.Launcher = l
|
|
|
+ //lxrod.Launcher.UserDataDir("user-data")
|
|
|
+ l.Flags["disable-blink-features"] = []string{"AutomationControlled"}
|
|
|
+ //if viper.GetString("env") == string(variable.Development) {
|
|
|
+ // l.Leakless(false) //开发环境不使用用leakless
|
|
|
+ //}
|
|
|
+ u := l.MustLaunch()
|
|
|
+
|
|
|
+ b = rod.New().ControlURL(u).MustConnect().NoDefaultDevice()
|
|
|
+ p = stealth.MustPage(b)
|
|
|
+ lxrod.Browser = b
|
|
|
+ go b.EachEvent(func(e *proto.TargetTargetCreated) {
|
|
|
+ defer func() {
|
|
|
+ if r := recover(); r != nil {
|
|
|
+
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ if e.TargetInfo.Type != proto.TargetTargetInfoTypePage {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page := b.MustPageFromTargetID(e.TargetInfo.TargetID)
|
|
|
+
|
|
|
+ _, err := page.EvalOnNewDocument(stealth.JS)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page.MustEvalOnNewDocument(stealth.JS)
|
|
|
+ page.MustSetUserAgent(nil)
|
|
|
+ utils.E(proto.RuntimeRunIfWaitingForDebugger{}.Call(page))
|
|
|
+ page.MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ })()
|
|
|
+ utils.E(proto.TargetSetAutoAttach{
|
|
|
+ AutoAttach: true,
|
|
|
+ WaitForDebuggerOnStart: true,
|
|
|
+ Flatten: true,
|
|
|
+ }.Call(b))
|
|
|
+ return b, p, err
|
|
|
+}
|
|
|
+
|
|
|
+// 最简单的浏览器创建
|
|
|
+func (lxrod *Lxrod) NewLowBrowser(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ if lxrod.Browser != nil {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ utils.Sleep(5)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ l := launcher.New().
|
|
|
+ Headless(false).
|
|
|
+ Set("high-dpi-support", "1").
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ Set("force-device-scale-factor", "1")
|
|
|
+ l.Flags["disable-blink-features"] = []string{"AutomationControlled"}
|
|
|
+ lxrod.Launcher = l
|
|
|
+ //lxrod.Launcher.UserDataDir("user-data")
|
|
|
+ //if lxrod.Area == "hebei" {
|
|
|
+ // lxrod.Launcher.UserDataDir("user-data")
|
|
|
+ //}
|
|
|
+ if lxrod.UseProxy {
|
|
|
+ lxrod.Proxy, lxrod.ProxyAuth = GetLocalProxy(string(lxrod.Area))
|
|
|
+ lxrod.Launcher.Proxy(lxrod.Proxy)
|
|
|
+ }
|
|
|
+ wsURL, err := l.Launch()
|
|
|
+
|
|
|
+ lxrod.WsURL = wsURL
|
|
|
+ if err != nil {
|
|
|
+ return nil, nil, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ b = rod.New().ControlURL(wsURL).Context(ctx).MustConnect()
|
|
|
+ utils.Sleep(1)
|
|
|
+ b = b.MustSetCookies()
|
|
|
+
|
|
|
+ if lxrod.UseProxy && lxrod.ProxyAuth != "" {
|
|
|
+ auths := strings.Split(lxrod.ProxyAuth, ":")
|
|
|
+ go b.HandleAuth(auths[0], auths[1])()
|
|
|
+ }
|
|
|
+ p = b.MustPage().MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+
|
|
|
+ if lxrod.MonitorDialog && lxrod.NoEachEventForCreated {
|
|
|
+ //为新打开的页面添加一个dialog监控
|
|
|
+ DialogWatch(ctx, p)
|
|
|
+ go b.EachEvent(func(e *proto.TargetTargetCreated) {
|
|
|
+ defer func() {
|
|
|
+ if r := recover(); r != nil {
|
|
|
+
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ if e.TargetInfo.Type != proto.TargetTargetInfoTypePage {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page := b.MustPageFromTargetID(e.TargetInfo.TargetID)
|
|
|
+ DialogWatch(ctx, page)
|
|
|
+ })()
|
|
|
+ }
|
|
|
+ lxrod.Browser = b
|
|
|
+ return b, p, nil
|
|
|
+}
|
|
|
+
|
|
|
+// NewBrowserBank360 打开 360 急速浏览器。适用于既要 ocx 密码输入又要 chrome 采集的银行任务,
|
|
|
+// 如承德银行。运行前需要先安装 360 急速浏览器,然后将 360 急速浏览器的安装目录添加到环境变量中。
|
|
|
+// 对于银行采集服务器,这个目录一般是:
|
|
|
+//
|
|
|
+// "C:\\Users\\taxrobot\\Desktop\\360Chrome1\\"
|
|
|
+func (lxrod *Lxrod) NewBrowserBank360(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+
|
|
|
+ bin, err := exec.LookPath("360chromeX.exe")
|
|
|
+ if err != nil {
|
|
|
+ return nil, nil, taxerr.NewUser("请先安装360极速浏览器(" + err.Error() + ")")
|
|
|
+ }
|
|
|
+
|
|
|
+ l := launcher.New().
|
|
|
+ Headless(false).
|
|
|
+ Bin(bin).
|
|
|
+ //Bin("C:\\Program Files (x86)\\税局小助手\\360Chrome\\360chromeX.exe").
|
|
|
+ Set("high-dpi-support", "1").
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ Set("force-device-scale-factor", "1")
|
|
|
+ l.Flags["disable-blink-features"] = []string{"AutomationControlled"}
|
|
|
+
|
|
|
+ lxrod.Launcher = l
|
|
|
+ wsURL, err := l.Launch()
|
|
|
+ lxrod.WsURL = wsURL
|
|
|
+ if err != nil {
|
|
|
+
|
|
|
+ return nil, nil, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ b = rod.New().ControlURL(wsURL).Context(ctx).MustConnect()
|
|
|
+ p = b.MustPage().MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+
|
|
|
+ if lxrod.MonitorDialog {
|
|
|
+ //为新打开的页面添加一个dialog监控
|
|
|
+ DialogWatch(ctx, p)
|
|
|
+ go b.EachEvent(func(e *proto.TargetTargetCreated) {
|
|
|
+ defer func() {
|
|
|
+ if r := recover(); r != nil {
|
|
|
+
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ if e.TargetInfo.Type != proto.TargetTargetInfoTypePage {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ page := b.MustPageFromTargetID(e.TargetInfo.TargetID)
|
|
|
+ DialogWatch(ctx, page)
|
|
|
+ })()
|
|
|
+ }
|
|
|
+ lxrod.Browser = b
|
|
|
+
|
|
|
+ return b, p, nil
|
|
|
+}
|
|
|
+
|
|
|
+// 最简单的浏览器创建2
|
|
|
+func (lxrod *Lxrod) NewLowBrowser2(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+ l := launcher.New().
|
|
|
+ Headless(false).
|
|
|
+ Set("high-dpi-support", "1").
|
|
|
+ Set("disable-features", "CalculateNativeWinOcclusion").
|
|
|
+ Set("force-device-scale-factor", "1")
|
|
|
+ l.Flags["disable-blink-features"] = []string{"AutomationControlled"}
|
|
|
+ lxrod.Launcher = l
|
|
|
+ //lxrod.Launcher.UserDataDir("user-data")
|
|
|
+ wsURL, err := l.Launch()
|
|
|
+ if err != nil {
|
|
|
+
|
|
|
+ return nil, nil, taxerr.NewWebStuckTitle(true)
|
|
|
+ }
|
|
|
+ b = rod.New().ControlURL(wsURL).Context(ctx).MustConnect()
|
|
|
+ p = b.MustPage().MustSetWindow(0, 0, 1600, 900).MustSetViewport(1600, 900, 1, false)
|
|
|
+ lxrod.Browser = b
|
|
|
+ if lxrod.MonitorDialog {
|
|
|
+ DialogWatch(ctx, p) //为新打开的页面添加一个dialog监控
|
|
|
+ }
|
|
|
+ if lxrod.UseProxy {
|
|
|
+ lxrod.Proxy, lxrod.ProxyAuth = GetLocalProxy(string(lxrod.Area))
|
|
|
+ lxrod.Launcher.Proxy(lxrod.Proxy)
|
|
|
+ }
|
|
|
+ return b, p, nil
|
|
|
+}
|
|
|
+
|
|
|
+// 自定义鼠标操作 方便升降版本
|
|
|
+type Mouse struct {
|
|
|
+ Mouse *rod.Mouse
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Mouse) MustMove(x, y float64) *Mouse {
|
|
|
+ m.Mouse.MustMoveTo(x, y)
|
|
|
+ return m
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Mouse) MustDown(button proto.InputMouseButton) *Mouse {
|
|
|
+ m.Mouse.MustDown(button)
|
|
|
+ return m
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Mouse) MustUp(button proto.InputMouseButton) *Mouse {
|
|
|
+ m.Mouse.MustUp(button)
|
|
|
+ return m
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Mouse) MustClick(button proto.InputMouseButton) *Mouse {
|
|
|
+ m.Mouse.MustClick(button)
|
|
|
+ return m
|
|
|
+}
|
|
|
+
|
|
|
+func ShenzhenProxy() string {
|
|
|
+ // 获取私密代理IP API
|
|
|
+ api := "https://dps.kdlapi.com/api/getdps"
|
|
|
+
|
|
|
+ // 请求参数
|
|
|
+ params := url.Values{}
|
|
|
+ params.Set("secret_id", "odr5kxfzzky69wbtuhzh")
|
|
|
+ params.Set("signature", "qwndesfg2ouix111a8rfzyixou7q9nr3")
|
|
|
+ params.Set("num", strconv.Itoa(1)) // 提取数量
|
|
|
+
|
|
|
+ // 构建完整的URL,包括参数
|
|
|
+ fullURL := api + "?" + params.Encode()
|
|
|
+
|
|
|
+ // 发送GET请求
|
|
|
+ response, err := http.Get(fullURL)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("Error:", err)
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ defer response.Body.Close()
|
|
|
+
|
|
|
+ // 读取响应内容
|
|
|
+ body, err := io.ReadAll(response.Body)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("Error reading response body:", err)
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+
|
|
|
+ // 输出响应结果
|
|
|
+ return "http://" + string(body)
|
|
|
+}
|
|
|
+
|
|
|
+// 备用
|
|
|
+func (lxrod *Lxrod) BeijingNew(ctx context.Context) (b *rod.Browser, p *rod.Page, err error) {
|
|
|
+ _ = rod.Try(func() {
|
|
|
+ lxrod.CloseBrowser()
|
|
|
+ })
|
|
|
+ l := launcher.New().Set("window-size", "1600,900").
|
|
|
+ Delete("enable-automation").
|
|
|
+ Leakless(true).
|
|
|
+ Headless(false).Set("disable-features", "CalculateNativeWinOcclusion")
|
|
|
+ l.Flags["disable-blink-features"] = []string{"AutomationControlled"}
|
|
|
+ u := l.MustLaunch()
|
|
|
+ b = rod.New().ControlURL(u).MustConnect()
|
|
|
+ p = b.MustPage("")
|
|
|
+ lxrod.Browser = b
|
|
|
+ return b, p, nil
|
|
|
+}
|
|
|
+
|
|
|
+// GetLocalProxy 获取所有地区代理 部分地区是使用的我们自己的代理池
|
|
|
+func GetLocalProxy(Area string) (string, string) {
|
|
|
+ // 都换成5879
|
|
|
+ if Area == "xizang" /*|| Area == "yunnan"*/ || Area == "hebei" || Area == "liaoning" || Area == "chongqing" || Area == "sichuan" {
|
|
|
+ return `http://8.141.85.129:5879`, "lxuser:Aa123456"
|
|
|
+ }
|
|
|
+ if Area == "yunnan" {
|
|
|
+ return "http://106.58.178.172:27237", "13280888700:nPDZ0RYX"
|
|
|
+ }
|
|
|
+ if Area == "shenzhen" {
|
|
|
+ return ShenzhenProxy(), "d2879234360:ikdnhzbk"
|
|
|
+ }
|
|
|
+ return `http://8.141.85.129:5879`, "lxuser:Aa123456"
|
|
|
+}
|