selenium 自动拖拽滑块以顺丰单号查询为例
-
网址: https://www.sf-express.com/we/ow/chn/sc/waybill/waybill-detail/SFxxxx 后面是订单编号
- 先看 滑块
- 这种滑块解决方案很多,本文是参照极验滑动验证码 ;获取滑动验证码完整背景和滑动时展现的背景,二者进行像素点比较,取最左侧不相同的像素点的位置left,即是我们要滑动的位置相对于图像最左侧的位置,届时再减去滑块按钮所在的x轴位置x_pos,就可以得到我们要滑动的长度。
- 此方案的难点在于如何获取完整的背景图(当然方法也不止一种)
- 先看 滑块
-
这里我们很容易就找到了缺块的背景图
文章来源:https://uudwc.com/A/MgVn
- 完整的背景图改如何获取呢,这时候笔者误打误撞发现了一个有意思的链接
- 这个
*
难道是一个分隔符 抱着试试的态度 访问了一下*
前面的链接 果然 - 有了完整图片剩下的不就好弄了
- 首先,把两张图片保存到本地(当然这里也可以参考极验 使用selenium带的截图功能,因为这里笔者没有找到限定的元素,没法使用js得到完整的背景,只能出此下策了)
- 使用selenium获取元素 这里要注意 等待 iframe 加载
- 关于拖动的时候注意 像素点;笔者这里就被坑了;你保存下来的图片大小和实际是有出入的,这里需要自己去计算
- 完整的背景图改如何获取呢,这时候笔者误打误撞发现了一个有意思的链接
-
最后附上代码(仅供参考)文章来源地址https://uudwc.com/A/MgVn
# Author: Lovy
# File : 04_滑块
# Time : 2022-08-20 16:25
import requests
from selenium import webdriver
from time import sleep
from PIL import Image
from selenium.webdriver import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
headers = {
'Referer': r'https://t.captcha.qq.com/cap_union_new_show?aid=2037219860&protocol=https&accver=1&showtype=popup&ua=TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV09XNjQpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS85OS4wLjQ4NDQuNTEgU2FmYXJpLzUzNy4zNg%3D%3D&noheader=1&fb=1&aged=0&enableAged=0&enableDarkMode=0&grayscale=1&clientype=2&userLanguage=zh-cn&sess=s0UU0F8r06RUZ9PBVu2eNVsgV_g9hGQrupqfh3xEkQPybQOkMmGtit-awx8nE2_VV1zQAtQHDxcaNsr1zRC1y8j3p9vdCMegNL6x43id3TLhDtZXtbOy8yCBnmpmibs6cSucWri9CjhUpxhw82wPr21EHtsg3QAhSunNBe4T3zeRtWhMDmDG5KEKXgPArssRGIUAHtVvvpznlJcmL3mthvyagLJaoYtsnIQRZbRjm5ATqRv5vGe-Pav3NWPRuAJkBSM8sj0hr-niA*&fwidth=0&sid=6966721938633166848&wxLang=&tcScale=1&uid=&cap_cd=&rnd=414726&prehandleLoadTime=113&createIframeStart=1660995944597&global=0&subsid=2',
'Host': 't.captcha.qq.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
}
class MyDriver():
def __init__(self):
self.x_pos = 0
self.option = webdriver.ChromeOptions()
self.driver = webdriver.Chrome(options=self.option)
self.driver.maximize_window()
self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})""",
})
def get_url(self, url):
self.driver.get(url)
sleep(5) # 如何显式等待 iframe加载
def switch_frame(self):
frame_element = self.driver.find_element('id', 'tcaptcha_iframe')
WebDriverWait(self.driver, 10, 0.5).until(
EC.frame_to_be_available_and_switch_to_it(frame_element))
element_locator = ('id', 'slideBg')
WebDriverWait(self.driver, 10, 0.5).until(
EC.visibility_of_element_located(element_locator))
def get_gap(self, image1, image2):
left = 60
for i in range(left, image1.size[0]):
for j in range(image1.size[1]):
if not self.is_pixel_equal(image1, image2, i, j):
left = i
return left
return left
def is_pixel_equal(self, image1, image2, x, y):
pixel1 = image1.load()[x, y]
pixel2 = image2.load()[x, y]
threshold = 60
if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(
pixel1[2] - pixel2[2]) < threshold:
return True
else:
return False
def img_cv(self):
img = self.driver.find_element('id', 'slideBg')
src = img.get_attribute('src')
img1 = requests.get(url=src, headers=headers)
with open("temp_img1.png", 'wb') as f:
f.write(img1.content)
img2 = requests.get(url=src[:417], headers=headers)
with open("temp_img2.png", 'wb') as f:
f.write(img2.content)
img1_ = Image.open('temp_img1.png')
img2_ = Image.open('temp_img2.png')
self.x_pos = self.get_gap(img1_, img2_)
def move(self, url):
self.get_url(url)
self.switch_frame()
self.img_cv()
ele_huakuai = self.driver.find_element('id', 'tcaptcha_drag_button')
ActionChains(self.driver, duration=1000).drag_and_drop_by_offset(ele_huakuai, self.x_pos // 2 - 35, 0).perform()
sleep(0.5)
self.driver.find_element('id', 'tcaptcha_drag_button').click()
if __name__ == '__main__':
url = "https://www.sf-express.com/we/ow/chn/sc/waybill/waybill-detail/SFxxxx" # 单号填自己的
mydriver = MyDriver()
mydriver.move(url)
- 最后在说一点利用Python+Selenium破解春秋航空网滑块验证码的实战过程这篇文章写的也不错;可以把所有的验证完整背景提前保存下来,对比背景图左上角顶点处的像素值,确定对应的背景,也是一种不错的思路