Browse Source

添加防水墙的过墙方法

Signed-off-by: 716 <[email protected]>
716 4 years ago
parent
commit
744f6bc23f
4 changed files with 154 additions and 0 deletions
  1. 2 0
      go.mod
  2. 12 0
      go.sum
  3. 135 0
      sub_supplier/subhd/subhd.go
  4. 5 0
      sub_supplier/subhd/subhd_test.go

+ 2 - 0
go.mod

@@ -7,5 +7,7 @@ require (
 	github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
 	github.com/beevik/etree v1.1.0
 	github.com/go-resty/resty/v2 v2.6.0
+	github.com/go-rod/rod v0.100.0
 	github.com/middelink/go-parse-torrent-name v0.0.0-20190301154245-3ff4efacd4c4
+	github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
 )

+ 12 - 0
go.sum

@@ -8,8 +8,20 @@ github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
 github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
 github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4=
 github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
+github.com/go-rod/rod v0.100.0 h1:tEKIb5wS3pGUpW4oJPYDxOKmRXaZbd6S+YVjJ6BHBBY=
+github.com/go-rod/rod v0.100.0/go.mod h1:h9igqSGReLmOWyHtdf0AtUd0mdkHFu3gFwBeV+stleM=
 github.com/middelink/go-parse-torrent-name v0.0.0-20190301154245-3ff4efacd4c4 h1:C/VViMMbR/4Ti2aXrWpKy34S05cRaVd6EvV9BFR3qJ8=
 github.com/middelink/go-parse-torrent-name v0.0.0-20190301154245-3ff4efacd4c4/go.mod h1:H66QhXPJpUSdWschhL6u//v3ge96/qMnQ9mWp3efbxA=
+github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
+github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
+github.com/ysmood/goob v0.3.0 h1:XZ51cZJ4W3WCoCiUktixzMIQF86W7G5VFL4QQ/Q2uS0=
+github.com/ysmood/goob v0.3.0/go.mod h1:S3lq113Y91y1UBf1wj1pFOxeahvfKkCk6mTWTWbDdWs=
+github.com/ysmood/got v0.12.0/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY=
+github.com/ysmood/gotrace v0.2.2/go.mod h1:TzhIG7nHDry5//eYZDYcTzuJLYQIkykJzCRIo4/dzQM=
+github.com/ysmood/gson v0.6.4 h1:Yb6tosv6bk59HqjZu2/7o4BFherpYEMkDkXmlhgryZ4=
+github.com/ysmood/gson v0.6.4/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg=
+github.com/ysmood/leakless v0.7.0 h1:XCGdaPExyoreoQd+H5qgxM3ReNbSPFsEXpSKwbXbwQw=
+github.com/ysmood/leakless v0.7.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=

+ 135 - 0
sub_supplier/subhd/subhd.go

@@ -1,19 +1,28 @@
 package subhd
 
 import (
+	"bytes"
 	"fmt"
 	"github.com/PuerkitoBio/goquery"
 	"github.com/allanpk716/ChineseSubFinder/common"
 	"github.com/allanpk716/ChineseSubFinder/sub_supplier"
+	"github.com/go-rod/rod"
+	"github.com/go-rod/rod/lib/devices"
+	"github.com/go-rod/rod/lib/launcher"
+	"github.com/nfnt/resize"
+	"image/jpeg"
+	"math"
 	"net/url"
 	"path/filepath"
 	"regexp"
 	"strings"
+	"time"
 )
 
 type Supplier struct {
 	reqParam common.ReqParam
 	topic int
+	rodlauncher *launcher.Launcher
 }
 
 func NewSupplier(_reqParam ... common.ReqParam) *Supplier {
@@ -265,6 +274,132 @@ func (s Supplier) httpPost(url string, postData map[string]string, referer strin
 	return resp.String(), nil
 }
 
+// Simulation 模拟滑动过防水墙
+func (s Supplier) Simulation() {
+	// 感谢 https://www.bigs3.com/article/gorod-crack-slider-captcha/
+	//設定設備參數
+	screen := devices.Device{
+		Title:          "Laptop with MDPI screen",
+		Capabilities:   []string{"touch", "mobile"},
+		UserAgent:      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
+		Screen: devices.Screen{
+			DevicePixelRatio: 1,
+			Horizontal: devices.ScreenSize{
+				Width:  1280,
+				Height: 720,
+			},
+		},
+	}
+	//設定啓動器
+	s.rodlauncher = launcher.New().
+		Set("mute-audio").
+		Set("default-browser-check").
+		Set("disable-gpu").
+		Set("disable-web-security").
+		Set("no-sandbox").
+		//關閉無頭模式,顯示瀏覽器窗體
+		Delete("headless")
+
+	//debug url
+	launchers := s.rodlauncher.MustLaunch()
+	fmt.Printf("debug url: %s\n", launchers)
+	//連接到瀏覽器
+	browser := rod.New().ControlURL(launchers).MustConnect()
+	//新開一個Pages
+	page := browser.DefaultDevice(screen).MustPage("")
+	//跳轉到目標網域
+	page.MustNavigate("https://007.qq.com/online.html").MustWaitLoad()
+
+	// 切换到可疑用户
+	page.MustElement("#app > section.wp-on-online > div > div > div > div.wp-on-box.col-md-5.col-md-offset-1 > div.wp-onb-tit > a:nth-child(2)").MustClick()
+	//模擬Click點擊 "體驗驗證碼" 按鈕
+	page.MustElement("#code").MustClick()
+	//等待驗證碼窗體載入
+	page.MustElement("#tcaptcha_iframe").MustWaitLoad()
+	//進入到iframe
+	iframe := page.MustElement("#tcaptcha_iframe").MustFrame()
+	//等待拖動條加載, 延遲500秒檢測變化, 以確認加載完畢
+	iframe.MustElement("#tcaptcha_drag_button").WaitStable(500 * time.Millisecond)
+	//等待缺口圖像載入
+	iframe.MustElement("#slideBg").MustWaitLoad()
+
+
+	//取得帶缺口圖像
+	shadowbg := iframe.MustElement("#slideBg").MustResource()
+	//取得原始圖像
+	src := iframe.MustElement("#slideBg").MustProperty("src")
+	fullbg, fileName, err := common.DownFile(strings.Replace(src.String(), "img_index=1", "img_index=0", 1))
+	if err != nil {
+		return
+	}
+	println(fileName)
+	//取得img展示的真實尺寸
+	bgbox := iframe.MustElement("#slideBg").MustShape().Box()
+	height, width := uint(math.Round(bgbox.Height)), uint(math.Round(bgbox.Width))
+	//裁剪圖像
+	shadowbg_img, _ := jpeg.Decode(bytes.NewReader(shadowbg))
+	shadowbg_img = resize.Resize(width, height, shadowbg_img, resize.Lanczos3)
+	fullbg_img, _ := jpeg.Decode(bytes.NewReader(fullbg))
+	fullbg_img = resize.Resize(width, height, fullbg_img, resize.Lanczos3)
+
+	//啓始left,排除干擾部份,所以右移10個像素
+	left := fullbg_img.Bounds().Min.X + 10
+
+	//啓始top, 排除干擾部份, 所以下移10個像素
+	top := fullbg_img.Bounds().Min.Y + 10
+
+	//最大left, 排除干擾部份, 所以左移10個像素
+	maxleft := fullbg_img.Bounds().Max.X - 10
+
+	//最大top, 排除干擾部份, 所以上移10個像素
+	maxtop := fullbg_img.Bounds().Max.Y - 10
+
+	//rgb比较阈值, 超出此阈值及代表找到缺口位置
+	threshold := 20
+
+	//缺口偏移, 拖動按鈕初始會偏移27.5
+	distance := -27.5
+
+	//取絕對值方法
+	abs := func(n int) int {
+		if n < 0 {
+			return -n
+		}
+		return n
+	}
+	search:
+	for i := left; i <= maxleft; i++ {
+		for j := top; j <= maxtop; j++ {
+			color_a_R, color_a_G, color_a_B, _ := fullbg_img.At(i, j).RGBA()
+			color_b_R, color_b_G, color_b_B, _ := shadowbg_img.At(i, j).RGBA()
+			color_a_R, color_a_G, color_a_B = color_a_R >> 8, color_a_G >> 8, color_a_B >> 8
+			color_b_R, color_b_G, color_b_B = color_b_R >> 8, color_b_G >> 8, color_b_B >> 8
+			if abs(int(color_a_R) - int(color_b_R)) > threshold ||
+				abs(int(color_a_G) - int(color_b_G)) > threshold ||
+				abs(int(color_a_B) - int(color_b_B)) > threshold {
+				distance += float64(i)
+				fmt.Printf("info: 對比完畢, 偏移量: %v\n", distance)
+				break search
+			}
+		}
+	}
+
+	//獲取拖動按鈕形狀
+	dragbtnbox := iframe.MustElement("#tcaptcha_drag_thumb").MustShape().Box()
+	//启用滑鼠功能
+	mouse := page.Mouse
+	//模擬滑鼠移動至拖動按鈕處, 右移3的原因: 拖動按鈕比滑塊圖大3個像素
+	mouse.MustMove(dragbtnbox.X + 3, dragbtnbox.Y + (dragbtnbox.Height / 2))
+	//按下滑鼠左鍵
+	mouse.MustDown("left")
+	//開始拖動
+	mouse.Move(dragbtnbox.X + distance, dragbtnbox.Y + (dragbtnbox.Height / 2), 20)
+	//鬆開滑鼠左鍵, 拖动完毕
+	mouse.MustUp("left")
+	//截圖保存
+	page.MustScreenshot("result.png")
+}
+
 type HdListItem struct {
 	Url        string `json:"url"`
 	BaseUrl    string `json:"baseUrl"`

+ 5 - 0
sub_supplier/subhd/subhd_test.go

@@ -21,3 +21,8 @@ func TestSupplier_GetSubListFromFile(t *testing.T) {
 		println(i, sublist.Name, sublist.Ext, sublist.Language.String(), sublist.Vote, sublist.FileUrl, len(sublist.Data))
 	}
 }
+
+func TestSupplier_Simulation(t *testing.T) {
+	shooter := NewSupplier()
+	shooter.Simulation()
+}