script.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. package script
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/tls"
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "github.com/chromedp/cdproto/browser"
  10. "github.com/chromedp/cdproto/network"
  11. "github.com/chromedp/cdproto/page"
  12. "github.com/chromedp/chromedp"
  13. "github.com/imroc/req/v3"
  14. "github.com/yuin/gopher-lua"
  15. "github.com/yuin/gopher-lua/parse"
  16. qu "jygit.jydev.jianyu360.cn/data_processing/common_utils"
  17. "net/http"
  18. "net/url"
  19. "os"
  20. "path/filepath"
  21. "spider_creator/backend"
  22. be "spider_creator/backend"
  23. "strconv"
  24. "strings"
  25. "time"
  26. )
  27. const (
  28. selector_type_id = 0
  29. selector_type_query = 1
  30. selector_type_search = 2
  31. selector_type_jspath = 3
  32. selector_type_query_all = 4
  33. execute_return_type_string = 0
  34. execute_return_type_list = 1
  35. execute_return_type_table = 2
  36. qlm_list_lua = "/qlm_list.lua"
  37. qlm_detail_lua = "/qlm_detail.lua"
  38. )
  39. var (
  40. DataCache = make(chan map[string]interface{}, 2000)
  41. Datas []map[string]interface{}
  42. )
  43. type GLVm struct {
  44. ScriptDir string
  45. LogsDir string
  46. LogsFile *os.File
  47. Dnf backend.EventNotifyFace
  48. Headless bool
  49. ShowImage bool
  50. ProxyServer bool
  51. ProxyAddr string
  52. B *GLBrowser
  53. ScriptRunning bool //控制一次只能执行一个脚本
  54. DataSaveOver chan bool
  55. }
  56. type GLBrowser struct {
  57. Ctx context.Context
  58. CancelFn context.CancelFunc
  59. }
  60. func NewGLVM(scriptDir, logsDir string, dnf be.EventNotifyFace) *GLVm {
  61. return &GLVm{
  62. ScriptDir: scriptDir,
  63. LogsDir: logsDir,
  64. Dnf: dnf,
  65. DataSaveOver: make(chan bool, 1),
  66. }
  67. }
  68. // LoadScript 加载脚本
  69. func (glvm *GLVm) LoadScript(page string) string {
  70. var path string
  71. if page == "list" {
  72. path = glvm.ScriptDir + qlm_list_lua
  73. } else if page == "detail" {
  74. path = glvm.ScriptDir + qlm_detail_lua
  75. }
  76. bs, err := os.ReadFile(path)
  77. if err != nil {
  78. qu.Debug(path, "脚本加载失败...")
  79. }
  80. return string(bs)
  81. }
  82. // RunScript 执行lua代码
  83. func (glvm *GLVm) RunScript(script, recordId string) error {
  84. defer qu.Catch()
  85. var s *lua.LState = lua.NewState()
  86. defer s.Close()
  87. //日志文件
  88. now := time.Now()
  89. path := glvm.LogsDir + fmt.Sprintf("/%s.log", qu.FormatDate(&now, qu.Date_Short_Layout))
  90. qu.Debug("log path:", path)
  91. file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
  92. if err != nil {
  93. qu.Debug("日志创建失败:", err)
  94. return err
  95. }
  96. glvm.LogsFile = file
  97. defer glvm.LogsFile.Close()
  98. //方法绑定
  99. glvm.ResetBrowser() //先创建浏览器对象
  100. glvm.BindLuaState(s) //绑定虚拟机函数
  101. glvm.B.BindLuaState(s, recordId)
  102. defer func() {
  103. if b := glvm.B; b != nil {
  104. b.CancelFn()
  105. b.Ctx = nil
  106. b.CancelFn = nil
  107. b = nil
  108. }
  109. }()
  110. reader := strings.NewReader(script)
  111. chunk, err := parse.Parse(reader, "code")
  112. if err != nil {
  113. return err
  114. }
  115. proto, err := lua.Compile(chunk, script)
  116. if err != nil {
  117. return err
  118. }
  119. lfunc := s.NewFunctionFromProto(proto)
  120. s.Push(lfunc)
  121. s.Call(0, 0)
  122. return nil
  123. }
  124. // ResetBrowser 重置浏览器
  125. func (glvm *GLVm) ResetBrowser() {
  126. if glvm.B != nil && glvm.B.CancelFn != nil {
  127. glvm.B.CancelFn()
  128. glvm.B.Ctx = nil
  129. glvm.B.CancelFn = nil
  130. }
  131. _, _, _, _, ctx, incCancelFn := backend.NewBrowser(glvm.Headless, glvm.ShowImage, glvm.ProxyServer, "http://")
  132. b := &GLBrowser{
  133. Ctx: ctx,
  134. CancelFn: incCancelFn,
  135. }
  136. if glvm.B == nil {
  137. glvm.B = b
  138. } else {
  139. glvm.B.Ctx, glvm.B.CancelFn = b.Ctx, b.CancelFn
  140. }
  141. }
  142. // BindLuaState 绑定虚拟机函数
  143. func (glvm *GLVm) BindLuaState(s *lua.LState) {
  144. s.SetGlobal("browser_reset", s.NewFunction(func(l *lua.LState) int {
  145. glvm.ResetBrowser()
  146. return 0
  147. }))
  148. s.SetGlobal("browser_savelog", s.NewFunction(func(l *lua.LState) int {
  149. text := l.ToString(-1)
  150. qu.Debug("log:", text)
  151. now := time.Now()
  152. glvm.LogsFile.Write([]byte(fmt.Sprintf("%s%s%s%s", qu.FormatDate(&now, qu.Date_Full_Layout), "---", text, "\n")))
  153. return 0
  154. }))
  155. }
  156. func (glvm *GLVm) CloseTabs() {
  157. if glvm.B != nil && glvm.B.CancelFn != nil {
  158. glvm.B.CancelFn()
  159. glvm.B.Ctx = nil
  160. glvm.B.CancelFn = nil
  161. glvm.B = nil
  162. }
  163. }
  164. // findTab 根据标题、url找tab
  165. func (b *GLBrowser) findTabContext(tabTitle, tabUrl string, timeoutInt64 int64) (ctx context.Context, err error) {
  166. if b.Ctx != nil {
  167. if timeoutInt64 == 0 {
  168. timeoutInt64 = 5000
  169. }
  170. timeout := time.Duration(timeoutInt64) * time.Millisecond
  171. if tabTitle == "" && tabUrl == "" {
  172. ctx, _ = context.WithTimeout(b.Ctx, timeout)
  173. return ctx, nil
  174. } else {
  175. ts, err := chromedp.Targets(b.Ctx)
  176. if err != nil {
  177. return nil, err
  178. }
  179. for _, t := range ts {
  180. if (tabTitle != "" && strings.Contains(t.Title, tabTitle)) || (tabUrl != "" && strings.Contains(t.URL, tabUrl)) {
  181. // log.Printf("find tab param<title,url>: %s %s found %s %s", tabTitle, tabUrl,
  182. // t.Title, t.URL)
  183. newCtx, _ := chromedp.NewContext(b.Ctx, chromedp.WithTargetID(t.TargetID))
  184. ctx, _ = context.WithTimeout(newCtx, timeout)
  185. return ctx, nil
  186. }
  187. }
  188. }
  189. return nil, errors.New("can't find tab")
  190. }
  191. return nil, errors.New("context is error")
  192. }
  193. // CloseTabs 关闭页面
  194. func (b *GLBrowser) CloseTabs(tabTitle, tabUrl string, timeoutInt64 int64) (err error) {
  195. if timeoutInt64 == 0 {
  196. timeoutInt64 = 5
  197. }
  198. timeout := time.Duration(timeoutInt64) * time.Millisecond
  199. ts, err := chromedp.Targets(b.Ctx)
  200. if err != nil {
  201. return err
  202. }
  203. for _, t := range ts {
  204. if (tabTitle != "" && strings.Contains(t.Title, tabTitle)) || (tabUrl != "" && strings.Contains(t.URL, tabUrl)) {
  205. newCtx, _ := chromedp.NewContext(b.Ctx, chromedp.WithTargetID(t.TargetID))
  206. ctx, _ := context.WithTimeout(newCtx, timeout)
  207. chromedp.Run(
  208. ctx,
  209. page.Close(),
  210. )
  211. }
  212. }
  213. return nil
  214. }
  215. // Navigate 导航到指定网址
  216. func (b *GLBrowser) Navigate(tabTitle string, tabUrl string, isNewTab bool, targetUrl string, timeout int64) (err error) {
  217. ctx, err := b.findTabContext(tabTitle, tabUrl, timeout)
  218. if err != nil {
  219. return err
  220. }
  221. //新标签页
  222. if isNewTab {
  223. ctx, _ = chromedp.NewContext(ctx)
  224. }
  225. //
  226. return chromedp.Run(ctx,
  227. chromedp.Navigate(targetUrl))
  228. }
  229. // Navigate 导航到指定网址,并保存请求资源,如图片等
  230. func (b *GLBrowser) NavigateAndSaveRes(tabTitle string, tabUrl string, timeout int64, isNewTab bool, targetUrl string, saveFileTypeList, save2dir string) (err error) {
  231. ctx, err := b.findTabContext(tabTitle, tabUrl, timeout)
  232. if err != nil {
  233. return err
  234. }
  235. //新标签页
  236. if isNewTab {
  237. ctx, _ = chromedp.NewContext(ctx)
  238. }
  239. //
  240. saveFileType := strings.Split(saveFileTypeList, " ")
  241. isNeedRes := func(fileType string) bool {
  242. for _, v := range saveFileType {
  243. if strings.Contains(fileType, v) {
  244. return true
  245. }
  246. }
  247. return false
  248. }
  249. fnURL2FileName := func(requestURL string) string {
  250. u, err := url.Parse(requestURL)
  251. if err != nil {
  252. return ""
  253. }
  254. _, filename := filepath.Split(u.Path)
  255. return filename
  256. }
  257. var cache = map[network.RequestID]string{}
  258. chromedp.ListenTarget(ctx, func(v interface{}) {
  259. switch ev := v.(type) {
  260. case *network.EventRequestWillBeSent: //准备下载
  261. cache[ev.RequestID] = ev.Request.URL
  262. case *network.EventResponseReceived: //检查回应头的contenttype
  263. contentType, _ := ev.Response.Headers["Content-Type"].(string)
  264. fmt.Println(contentType)
  265. if !isNeedRes(contentType) {
  266. delete(cache, ev.RequestID)
  267. }
  268. case *network.EventLoadingFinished: //下载完成
  269. if uri, ok := cache[ev.RequestID]; ok {
  270. filename := fnURL2FileName(uri)
  271. fmt.Println("save2file", filename)
  272. if filename != "" {
  273. filePath := filepath.Join(save2dir, filename)
  274. var buf []byte
  275. if err := chromedp.Run(ctx, chromedp.ActionFunc(func(ctx context.Context) error {
  276. var err error
  277. buf, err = network.GetResponseBody(ev.RequestID).Do(ctx)
  278. return err
  279. })); err == nil {
  280. os.WriteFile(filePath, buf, 0777)
  281. } else {
  282. fmt.Println(err.Error())
  283. }
  284. }
  285. }
  286. }
  287. })
  288. //
  289. err = chromedp.Run(ctx,
  290. chromedp.Navigate(targetUrl))
  291. //下载存储
  292. return err
  293. }
  294. // ExecuteJS 执行脚本
  295. func (b *GLBrowser) ExecuteJS(tabTitle, tabUrl, script string, ret interface{}, timeout int64) (err error) {
  296. ctx, err := b.findTabContext(tabTitle, tabUrl, timeout)
  297. if err != nil {
  298. return err
  299. }
  300. return chromedp.Run(ctx,
  301. chromedp.Evaluate(script, ret))
  302. }
  303. // Click 点击
  304. func (b *GLBrowser) Click(tabTitle, tabUrl, selector string, selectorType int, timeout int64) (err error) {
  305. ctx, err := b.findTabContext(tabTitle, tabUrl, timeout)
  306. if err != nil {
  307. return err
  308. }
  309. var act chromedp.QueryAction
  310. switch selectorType {
  311. case selector_type_id:
  312. act = chromedp.Click(selector, chromedp.ByID)
  313. case selector_type_query:
  314. act = chromedp.Click(selector, chromedp.ByQuery)
  315. case selector_type_search:
  316. act = chromedp.Click(selector, chromedp.BySearch)
  317. case selector_type_jspath:
  318. act = chromedp.Click(selector, chromedp.ByJSPath)
  319. default:
  320. act = chromedp.Click(selector, chromedp.ByQueryAll)
  321. }
  322. err = chromedp.Run(ctx,
  323. act)
  324. return err
  325. }
  326. // KeySend 键盘输入
  327. func (b *GLBrowser) KeySend(tabTitle, tabUrl, selector, sendStr string, selectorType int, timeout int64) (err error) {
  328. ctx, err := b.findTabContext(tabTitle, tabUrl, timeout)
  329. if err != nil {
  330. return err
  331. }
  332. var act chromedp.QueryAction
  333. switch selectorType {
  334. case selector_type_id:
  335. act = chromedp.SendKeys(selector, sendStr, chromedp.ByID)
  336. case selector_type_query:
  337. act = chromedp.SendKeys(selector, sendStr, chromedp.ByQuery)
  338. case selector_type_search:
  339. act = chromedp.SendKeys(selector, sendStr, chromedp.BySearch)
  340. case selector_type_jspath:
  341. act = chromedp.SendKeys(selector, sendStr, chromedp.ByJSPath)
  342. default:
  343. act = chromedp.SendKeys(selector, sendStr, chromedp.ByQueryAll)
  344. }
  345. return chromedp.Run(ctx,
  346. act)
  347. }
  348. // WaitVisible 等待元素可见
  349. func (b *GLBrowser) WaitVisible(tabTitle, tabUrl, selector string, selectorType int, timeout int64) error {
  350. ctx, err := b.findTabContext(tabTitle, tabUrl, timeout)
  351. if err != nil {
  352. return err
  353. }
  354. var act chromedp.QueryAction
  355. switch selectorType {
  356. case selector_type_id:
  357. act = chromedp.WaitVisible(selector, chromedp.ByID)
  358. case selector_type_query:
  359. act = chromedp.WaitVisible(selector, chromedp.ByQuery)
  360. case selector_type_search:
  361. act = chromedp.WaitVisible(selector, chromedp.BySearch)
  362. case selector_type_jspath:
  363. act = chromedp.WaitVisible(selector, chromedp.ByJSPath)
  364. default:
  365. act = chromedp.WaitVisible(selector, chromedp.ByQueryAll)
  366. }
  367. return chromedp.Run(ctx,
  368. act)
  369. }
  370. // 重置浏览器
  371. func (b *GLBrowser) Reset() {
  372. }
  373. // DownloadFile 只有在非headless模式下有效,与click方法其实是一致的
  374. func (b *GLBrowser) DownloadFile(tabTitle, tabUrl string, timeout int64, selector string, selectorType int, save2dir string) error {
  375. ctx, err := b.findTabContext(tabTitle, tabUrl, timeout)
  376. if err != nil {
  377. return err
  378. }
  379. var act chromedp.QueryAction
  380. switch selectorType {
  381. case selector_type_id:
  382. act = chromedp.Click(selector, chromedp.ByID)
  383. case selector_type_query:
  384. act = chromedp.Click(selector, chromedp.ByQuery)
  385. case selector_type_search:
  386. act = chromedp.Click(selector, chromedp.BySearch)
  387. case selector_type_jspath:
  388. act = chromedp.Click(selector, chromedp.ByJSPath)
  389. default:
  390. act = chromedp.Click(selector, chromedp.ByQueryAll)
  391. }
  392. return chromedp.Run(ctx,
  393. browser.SetDownloadBehavior(browser.SetDownloadBehaviorBehaviorAllowAndName).WithDownloadPath(save2dir).WithEventsEnabled(true),
  394. act)
  395. }
  396. func (b *GLBrowser) AnalysisCode(path, stype, head, cookie string, proxy bool) (code string, rh http.Header, rc []*http.Cookie) {
  397. //先用免费,为识别再用收费
  398. ok := false
  399. code, rh, rc, _, ok = getCodeByFree(path, stype, head, cookie, proxy) //自己的服务
  400. qu.Debug("Get Code By Free Result:", path, ok, code)
  401. if qu.IntAll(stype) > 0 && !ok {
  402. code, rh, rc = getCodeByPay(path, stype, head, cookie, proxy) //超级鹰收费
  403. }
  404. return
  405. }
  406. func getCodeByFree(path, stype, head, cookie string, proxy bool) (code string, respheader http.Header, respcookie []*http.Cookie, getCodeResp *req.Response, ok bool) {
  407. defer qu.Catch()
  408. client := req.C().
  409. SetTimeout(time.Duration(be.Cfg.ServerCodeTimeOut) * time.Second).
  410. SetTLSClientConfig(&tls.Config{
  411. Renegotiation: tls.RenegotiateOnceAsClient,
  412. InsecureSkipVerify: true,
  413. }) //忽略证书验证
  414. headers := map[string]string{}
  415. if head != "" {
  416. json.Unmarshal([]byte(head), &headers)
  417. }
  418. cookies := []*http.Cookie{}
  419. if cookie != "" {
  420. json.Unmarshal([]byte(cookie), &cookies)
  421. }
  422. for times := 1; times <= 6; times++ { //重试三次
  423. if times > 2 || proxy { //重试第4次开始,使用代理ip
  424. if stype == "-1" {
  425. return
  426. }
  427. proxyIp := be.GetProxyAddr() //获取代理地址
  428. qu.Debug("proxy:", path, proxyIp)
  429. client.SetProxyURL(proxyIp) //设置代理IP
  430. }
  431. request := client.R()
  432. if len(headers) > 0 {
  433. request.SetHeaders(headers)
  434. }
  435. if len(cookies) > 0 {
  436. request.SetCookies(cookies...)
  437. }
  438. //下载验证码图片
  439. var err error
  440. var resultByte []byte
  441. address := be.Cfg.ServerCodeFreeAddressOcr
  442. if stype == "-1" { //传base64的图片
  443. resultByte = []byte(path)
  444. } else {
  445. if stype == "6001" { //计算类验证码解析接口地址
  446. address = be.Cfg.ServerCodeFreeAddressArithmetic
  447. }
  448. getCodeResp, err = request.Get(path) //通过请求图片地址返回的byte
  449. resultByte = getCodeResp.Bytes()
  450. }
  451. if err != nil {
  452. qu.Debug("Get Code By Path Error: ", path, err)
  453. continue
  454. }
  455. //解析验证码
  456. codeResp, err := client.R().
  457. SetHeader("accept", "application/json").
  458. SetFileReader("file", "1", bytes.NewReader(resultByte)).
  459. Post(address)
  460. if err != nil {
  461. qu.Debug("analysis code by path err: ", path, err)
  462. continue
  463. }
  464. yzmResult := map[string]interface{}{}
  465. json.Unmarshal(codeResp.Bytes(), &yzmResult)
  466. qu.Debug(path, yzmResult)
  467. result := yzmResult["r"].(map[string]interface{})
  468. yzm := fmt.Sprint(result["code"])
  469. if yzm != "" {
  470. if stype == "6001" || len(yzm) >= 4 {
  471. code = yzm //长度小于4的视为识别错误
  472. if getCodeResp != nil {
  473. respheader = getCodeResp.Header
  474. respcookie = getCodeResp.Cookies()
  475. }
  476. ok = true
  477. return
  478. }
  479. }
  480. }
  481. return
  482. }
  483. func getCodeByPay(path, stype, head, cookie string, proxy bool) (code string, respheader http.Header, respcookie []*http.Cookie) {
  484. defer qu.Catch()
  485. client := req.C().
  486. SetTimeout(time.Duration(be.Cfg.ServerCodeTimeOut) * time.Second).
  487. SetTLSClientConfig(&tls.Config{
  488. Renegotiation: tls.RenegotiateOnceAsClient,
  489. InsecureSkipVerify: true,
  490. }) //忽略证书验证
  491. headers := map[string]string{}
  492. if head != "" {
  493. json.Unmarshal([]byte(head), &headers)
  494. }
  495. cookies := []*http.Cookie{}
  496. if cookie != "" {
  497. json.Unmarshal([]byte(cookie), &cookies)
  498. }
  499. for times := 1; times <= 2; times++ { //重试三次
  500. //atomic.AddInt64(&PyTimes, 1)
  501. if times > 1 || proxy { //重试第2次开始,使用代理ip
  502. proxyIp := be.GetProxyAddr() //获取代理地址
  503. qu.Debug("proxy:", path, proxyIp)
  504. client.SetProxyURL(proxyIp) //设置代理IP
  505. }
  506. request := client.R()
  507. if len(headers) > 0 {
  508. request.SetHeaders(headers)
  509. }
  510. if len(cookies) > 0 {
  511. request.SetCookies(cookies...)
  512. }
  513. //下载验证码图片
  514. getCodeResp, err := request.Get(path)
  515. //log.Println("respHeader---", getCodeResp.Header)
  516. //log.Println("respCookie---", getCodeResp.Cookies())
  517. if err != nil {
  518. qu.Debug("Get Code By Path Error: ", path, err)
  519. continue
  520. }
  521. //解析验证码
  522. data := map[string]string{
  523. "grant_type": "",
  524. "username": "jianyu001",
  525. "password": "123qwe!A",
  526. "scope": "",
  527. "client_id": "",
  528. "client_secret ": "",
  529. }
  530. codeResp, err := client.R().
  531. SetHeader("accept", "application/json").
  532. SetFileReader("file", "1", bytes.NewReader(getCodeResp.Bytes())).
  533. SetFormData(data).
  534. Post(be.Cfg.ServerCodeAddress + stype)
  535. //SetFile("file", "C:/Users/topnet/Desktop/code.jpg").
  536. // Post(spiderutil.Config.ServerCodeAddress)
  537. if err != nil {
  538. qu.Debug("analysis code by path err: ", path, err)
  539. continue
  540. }
  541. codeResult := map[string]interface{}{}
  542. json.Unmarshal(codeResp.Bytes(), &codeResult)
  543. qu.Debug("codeResult:", codeResult)
  544. if yzm, ok := codeResult["r"].(map[string]interface{})["pic_str"].(string); ok && yzm != "" && len(yzm) >= 4 {
  545. code = yzm
  546. respheader = getCodeResp.Header
  547. respcookie = getCodeResp.Cookies()
  548. return
  549. }
  550. }
  551. return
  552. }
  553. // BindLuaState
  554. func (b *GLBrowser) BindLuaState(s *lua.LState, recordId string) {
  555. //执行暂停
  556. s.SetGlobal("browser_sleep", s.NewFunction(func(l *lua.LState) int {
  557. fmt.Println("---browser_sleep---")
  558. timeout := l.ToInt64(-1)
  559. if timeout == 0 {
  560. timeout = 5
  561. }
  562. time.Sleep(time.Duration(timeout) * time.Millisecond)
  563. return 0
  564. }))
  565. //关闭tabl页
  566. s.SetGlobal("browser_closetabs", s.NewFunction(func(l *lua.LState) int {
  567. fmt.Println("---browser_closetabs---")
  568. timeout := l.ToInt64(-3)
  569. tabTitle := l.ToString(-2)
  570. tabUrl := l.ToString(-1)
  571. if timeout == 0 {
  572. timeout = 5
  573. }
  574. b.CloseTabs(tabTitle, tabUrl, timeout)
  575. return 0
  576. }))
  577. //注册打开地址
  578. s.SetGlobal("browser_navagite", s.NewFunction(func(l *lua.LState) int {
  579. fmt.Println("---browser_navagite---")
  580. tabTitle := l.ToString(-5) //指定标签页title
  581. tabUrl := l.ToString(-4) //指定标签页url
  582. isNewTab := l.ToBool(-3) //是否打开新的标签页
  583. timeout := l.ToInt64(-2) //网页打开的超时时间
  584. targetUrl := l.ToString(-1) //打开网页的链接
  585. if err := b.Navigate(tabTitle, tabUrl, isNewTab, targetUrl, timeout); err != nil {
  586. l.Push(lua.LString(err.Error()))
  587. } else {
  588. l.Push(lua.LString("ok"))
  589. }
  590. return 1
  591. }))
  592. //执行浏览器端js
  593. s.SetGlobal("browser_executejs", s.NewFunction(func(l *lua.LState) int {
  594. fmt.Println("---browser_executejs---")
  595. tabTitle := l.ToString(-5)
  596. tabUrl := l.ToString(-4)
  597. timeout := l.ToInt64(-3)
  598. returnType := l.ToInt(-2) //返回数据类型
  599. script := l.ToString(-1) //执行的js
  600. switch returnType {
  601. case execute_return_type_string: //返回string
  602. var ret string
  603. if err := b.ExecuteJS(tabTitle, tabUrl, script, &ret, timeout); err == nil {
  604. l.Push(lua.LString("ok"))
  605. l.Push(lua.LString(ret))
  606. } else {
  607. l.Push(lua.LString("err"))
  608. l.Push(lua.LString(err.Error()))
  609. }
  610. case execute_return_type_list: //返回list
  611. var ret = make([]interface{}, 0, 0)
  612. var tmp = make(map[string]interface{})
  613. if err := b.ExecuteJS(tabTitle, tabUrl, script, &ret, timeout); err == nil {
  614. for i, v := range ret {
  615. tmp[strconv.Itoa(i)] = v
  616. }
  617. l.Push(lua.LString("ok"))
  618. l.Push(MapToTable(tmp))
  619. } else {
  620. l.Push(lua.LString("err"))
  621. l.Push(lua.LString(err.Error()))
  622. }
  623. case execute_return_type_table: //返回table
  624. var ret = make(map[string]interface{})
  625. if err := b.ExecuteJS(tabTitle, tabUrl, script, &ret, timeout); err == nil {
  626. l.Push(lua.LString("ok"))
  627. l.Push(MapToTable(ret))
  628. } else {
  629. l.Push(lua.LString("err"))
  630. l.Push(lua.LString(err.Error()))
  631. }
  632. }
  633. return 2
  634. }))
  635. //按键
  636. s.SetGlobal("browser_keysend", s.NewFunction(func(l *lua.LState) int {
  637. fmt.Println("---browser_keysend---")
  638. tabTitle := l.ToString(-6)
  639. tabUrl := l.ToString(-5)
  640. timeout := l.ToInt64(-4)
  641. words := l.ToString(-3)
  642. selectorType := l.ToInt(-2)
  643. selector := l.ToString(-1)
  644. fmt.Println(selector, words, selectorType, timeout)
  645. err := b.KeySend(tabTitle, tabUrl, selector, words, selectorType, timeout)
  646. if err != nil {
  647. l.Push(lua.LString(err.Error()))
  648. } else {
  649. l.Push(lua.LString("ok"))
  650. }
  651. return 1
  652. }))
  653. //点击
  654. s.SetGlobal("browser_click", s.NewFunction(func(l *lua.LState) int {
  655. fmt.Println("---browser_click---")
  656. tabTitle := l.ToString(-5)
  657. tabUrl := l.ToString(-4)
  658. timeout := l.ToInt64(-3)
  659. selectorType := l.ToInt(-2)
  660. selector := l.ToString(-1)
  661. err := b.Click(tabTitle, tabUrl, selector, selectorType, timeout)
  662. if err != nil {
  663. l.Push(lua.LString(err.Error()))
  664. } else {
  665. l.Push(lua.LString("ok"))
  666. }
  667. return 1
  668. }))
  669. //等待元素加载
  670. s.SetGlobal("browser_waitvisible", s.NewFunction(func(l *lua.LState) int {
  671. fmt.Println("---browser_waitvisible---")
  672. tabTitle := l.ToString(-5)
  673. tabUrl := l.ToString(-4)
  674. timeout := l.ToInt64(-3)
  675. selectorType := l.ToInt(-2) //选择器类型
  676. selector := l.ToString(-1) //选择器
  677. err := b.WaitVisible(tabTitle, tabUrl, selector, selectorType, timeout)
  678. if err != nil {
  679. l.Push(lua.LString(err.Error()))
  680. } else {
  681. l.Push(lua.LString("ok"))
  682. }
  683. return 1
  684. }))
  685. //下载附件
  686. s.SetGlobal("browser_downloadfile", s.NewFunction(func(l *lua.LState) int {
  687. tabTitle := l.ToString(-6)
  688. tabUrl := l.ToString(-5)
  689. timeout := l.ToInt64(-4)
  690. selectorType := l.ToInt(-3)
  691. selector := l.ToString(-2)
  692. save2dir := l.ToString(-1)
  693. err := b.DownloadFile(tabTitle, tabUrl, timeout, selector, selectorType, save2dir)
  694. if err != nil {
  695. l.Push(lua.LString(err.Error()))
  696. } else {
  697. l.Push(lua.LString("ok"))
  698. }
  699. return 1
  700. }))
  701. //注册打开地址
  702. s.SetGlobal("browser_navagite_download_res", s.NewFunction(func(l *lua.LState) int {
  703. tabTitle := l.ToString(-7)
  704. tabUrl := l.ToString(-6)
  705. timeout := l.ToInt64(-5)
  706. isNewTab := l.ToBool(-4)
  707. targetUrl := l.ToString(-3)
  708. saveFileTypeList := l.ToString(-2)
  709. savedir := l.ToString(-1)
  710. if err := b.NavigateAndSaveRes(tabTitle, tabUrl, timeout, isNewTab, targetUrl, saveFileTypeList, savedir); err != nil {
  711. l.Push(lua.LString(err.Error()))
  712. } else {
  713. l.Push(lua.LString("ok"))
  714. }
  715. return 1
  716. }))
  717. s.SetGlobal("browser_analysiscode", s.NewFunction(func(S *lua.LState) int {
  718. cookie := S.ToString(-1)
  719. head := S.ToTable(-2)
  720. stype := S.ToString(-3)
  721. path := S.ToString(-4)
  722. proxy := S.ToBool(-5)
  723. headMap := TableToMap(head)
  724. //qu.Debug("cookie----------", cookie)
  725. //qu.Debug("headMap----------", headMap)
  726. headJsonStr := ""
  727. headByte, err := json.Marshal(headMap)
  728. if err == nil {
  729. headJsonStr = string(headByte)
  730. }
  731. code, respHead, respCookie := b.AnalysisCode(path, stype, headJsonStr, cookie, proxy)
  732. rhead, _ := json.Marshal(respHead)
  733. respHeadMap := map[string]interface{}{}
  734. json.Unmarshal(rhead, &respHeadMap)
  735. hTable := MapToTable(respHeadMap)
  736. rcookie, _ := json.Marshal(respCookie)
  737. respCookieMap := []map[string]interface{}{}
  738. json.Unmarshal(rcookie, &respCookieMap)
  739. cTable := MapToTable(map[string]interface{}{"cookie": respCookieMap})
  740. S.Push(lua.LString(code))
  741. S.Push(hTable)
  742. S.Push(cTable.RawGetString("cookie"))
  743. return 3
  744. }))
  745. //发布时间格式化
  746. s.SetGlobal("browser_publishtime", s.NewFunction(func(l *lua.LState) int {
  747. text := l.ToString(-1)
  748. publishtime := getPublitime(text)
  749. l.Push(lua.LString(publishtime))
  750. return 1
  751. }))
  752. //保存数据
  753. s.SetGlobal("browser_savedata", s.NewFunction(func(l *lua.LState) int {
  754. //fmt.Println("---browser_savedata---")
  755. page := l.ToString(-2)
  756. data := l.ToTable(-1)
  757. result := TableToMap(data)
  758. if page == "list" {
  759. result["recordid"] = recordId
  760. }
  761. DataCache <- result
  762. return 1
  763. }))
  764. //获取数据
  765. s.SetGlobal("browser_getdata", s.NewFunction(func(l *lua.LState) int {
  766. fmt.Println("---browser_getdata---")
  767. num := l.ToInt(-1) //获取多少条数据
  768. count := len(Datas)
  769. if count == 0 {
  770. l.Push(lua.LString("err"))
  771. l.Push(lua.LString("当前可下载量为0"))
  772. } else {
  773. if count < num {
  774. num = count
  775. }
  776. data := Datas[:num]
  777. Datas = Datas[num:]
  778. tMap := MapToTable(map[string]interface{}{"data": data})
  779. l.Push(lua.LString("ok"))
  780. l.Push(tMap.RawGetString("data"))
  781. }
  782. return 2
  783. }))
  784. }