我一直在抓取这个网站:https://www.immobilienscout24.de
当用selenium打开网站时,网站有时会在你点击“你不是机器人”验证码后给你解决一个谜题验证码。问题是该网站只允许你移动拼图 6 次。如果您在第六次之后未能将拼图放在正确的位置,将禁止您进入该网站。
代码移动了拼图,但是我如何安排 for 循环将屏幕分成 6 个确切的部分?或者如果有人有某种不同的方法?
拼图验证码的代码如下:
try:
slider = driver.find_element(By.CLASS_NAME, 'geetest_slider_button')
for x in range(0, 200, 10):
actions.move_to_element(slider).click_and_hold().move_by_offset(x, 0).release().perform()
time.sleep(0.1)
except:
print('No slider found. Continuing with the code.')
谢谢你。
根据我对您问题的理解,您的目标是在六次尝试内验证图片验证码。
这是一个非常复杂的问题,我认为最好的解决方案是直接将图像交给AI进行图像排序,这样会更容易。但我没有调用相关AI API的资格。也许您可以尝试激活它们。至于调用AI的代码,我觉得并不难。
排除使用AI的可能性,我相信仅仅通过模拟拖放来达到你的目标是不会成功的。
首先,您需要通过任何必要的手段捕获验证码区域,最终获得六张无序图像。例如,您可以捕获单个无序图像,然后在本地对其进行切片,或者直接从网页源代码中获取图像资源。
假设您已经完成这一步并获得了六张图像,您可以继续合并它们并进行图像采样。采样的方式有很多种,比如先将图像设置为灰度,然后进行轮廓提取。这样,您就得到了等高线图。一般来说,由于单幅图像存在亮度梯度,图像之间会有明显的分割线。当然,为了得到这些不同的特征线,你可能需要在轮廓提取过程中不断改变参数。不过由于图片已经下载到本地了,所以还是可以暴力破解这个问题。
大多数情况下,我们在边缘测试中无法达到100%的匹配,因此需要为每个边缘匹配结果建立特征值。完成序列的所有排列组合后,使用最高的特征值来移动图像。如果仍有剩余尝试次数,您可以继续使用排名较低的序列。
您可能会问,当您没有绝对正确的图像进行边缘匹配比较时,如何建立特征值。我的想法是你可以扭转你的做法。例如,手动创建空白图像,并在分割线的位置人为地绘制对比线。之后,提取该图像的轮廓作为你的特征值的参考。
另外,另一个想法是直接对这六张图像应用边缘匹配算法,将它们成对匹配,并计算最终的匹配值。
以上是我的思考过程,下面可能是该过程中涉及的潜在代码。
def match_edges(image1, image2):
# Convert images to grayscale
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
# Detect edges in the images using the Canny algorithm
edges1 = cv2.Canny(gray1, 50, 150)
edges2 = cv2.Canny(gray2, 50, 150)
# Initialize variables for matching edges
# This example simplifies the matching process for demonstration purposes
height, width = edges1.shape
best_match_value = float('inf')
best_match_position = None
# Assuming edge matching is performed side by side (left/right edges comparison)
for y in range(height):
# Calculate the difference between edges of the two images
match_value = np.sum(np.bitwise_xor(edges1[y,:], edges2[y,:]))
# Update the best match if the current match is better
if match_value < best_match_value:
best_match_value = match_value
best_match_position = y
# Return the position and value of the best match
return best_match_position, best_match_value
# Restore picture
f = merge(sum_rows,sum_cols,channels,part1,part2,part3,part4)
show_images([f],'Restore picture[1,2,3,4]')
# Gray
gray = cv2.cvtColor(f, cv2.COLOR_BGRA2GRAY)
show_images([gray],'Gray')
# Extract contour
edges = cv2.Canny(gray, 35, 80, apertureSize=3)
show_images([edges],'Extract contour')
# f is current unsorted merge-image
f = merge(sum_rows,sum_cols,channels,part1,part2,part3,part4)
lf = f.copy()
cv2.line(lf, (0, 75), (300, 75), (0, 0, 255), 2)
cv2.line(lf, (150, 0), (150, 150), (0, 0, 255), 2)
show_images([lf],'out of order,The gradient becomes the cross feature line.')
f = merge(sum_rows,sum_cols,channels,part1,part2,part3,part4)
gray = cv2.cvtColor(f, cv2.COLOR_BGRA2GRAY)
edges = cv2.Canny(gray, 35, 80, apertureSize=3)
show_images([edges],'Extract contour')
# find the split line.
lines = cv2.HoughLinesP(edges,0.01,np.pi/360,60,minLineLength=50,maxLineGap=10)
if lines is None:
print('No cross feature line found')
else:
lf = f.copy()
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(lf, (x1, y1), (x2, y2), (0, 0, 255), 2)
show_images([lf])
Reference:
platform.openai.com/docs/guides/function-calling
zhihu.com/p/434851845
geeksforgeeks.org/feature-detection-and-matching-with-opencv-python