Advanced crawler combat: cracking the extreme sliding verification code

Today I bring you the selenium cracking method of the verification code. Are you a little excited? My friends can't wait, let's go straight to the topic.

Tiger X Network Registration

This time, we used Tiger X to operate. When registering an account, we need to slide the picture to the gap position. We often encounter this kind of verification code now, so there is no need to introduce this in detail.

For this kind of verification code, we first determined the use of selenium to simulate the sliding cracking method. Selenium mouse movement, click and drag are relatively simple, so the question is how far to drag, the eyes look very intuitive, but how to obtain the program? Using image recognition... um, I can only think about it. It is better to look at the source code of the webpage or request information to see if there is any valid information.

View web page information

Right-click on the image to view the element

The picture at this moment, fortunately, my unicorn arm has not been practiced in vain for more than 20 years. Let's see what the elements see.

This looks a bit strange, there is a picture link, and location information, and there are so many, first copy the picture link into the browser and visit it


WTF, what the hell is this? Notice that 6 that looks like a pig's tail? There is also the small arrow, compared with the complete picture above, and found that moving the arrow to the side of the small 6, the pig tail is successful. Of course, if you look closely, there are other things such as text that are similar. Then we can confirm that this picture should be scrambled. If we can put it together, is it closer to calculating the position of the gap. Now we should pay attention to the position information behind the element view, so much, it seems that it should have something to do with this disordered order. Let's make sure. My idea is like this, since this position is related to the puzzle, and look at the picture of our unicorn arm above, I will mark it again

When we click to view the element, the browser will highlight it for us. Originally, I clicked on the image to view it. According to my idea, shouldn't it be highlighted on the entire image? It seems that this is not the case, there is only a small part, and there are element information, width and height class names on it, go back and look at Figure 3, in the position coordinates, the front should be the x-axis, the back is the y-axis, and the y-axis There are only 58 and 0. According to Figure 2, the picture is divided into upper and lower parts. Count the number of divs. There are 26 pieces, each with a width of 10x a height of 58. According to this calculation, then the width of the whole picture is 260, and the height is 116. Use the screenshot tool to pull the width and height of the picture, which basically matches.

接下来就是确定怎么拼了。这里很抱歉的告诉大家,猪没了,等我写到这里再去查看网页的时候,图片已经刷新了。所以接下来的截图可能不一样,在这里提前跟大家说明一下。反正就是找特征点嘛,每个图片应该都有的。先随便找一个特征点,查看元素,看它定位到那个div元素那里,然后再看看后面的位置。基本就是这样,所以我们找图片既然和位置有关,那么我们最好选一些位置明显的地方,比如中间,或者两边。


这个差不多算中间位置了吧,查那么一点点无所谓了

我去,这……跟我想的不太一样呀,再找两张看看,代表性及其强烈的


 

为了防止有人说我水字数,另外两个角就不截图了。到这一步可能有人纳闷了,为啥?你刚才说图片宽度260,为什么坐标里出现了289这样的坐标,这不就是超标了吗?一开始我也有这样的疑惑,可能我们看到图片比实际的小,也许人家在图片外面还留了边框呢,我一开始是这么想的。但是这个坐标是前面url里面的图片坐标,然后我就去看了一下图4


这个图片尽然比较大,坐标问题有答案了,但是这个跟260有什么关系呢?打乱的图片比较大,拼好的小,那它是怎么拼的呢?幸好我们看到了一个比较有用信息

看到这个-1px了吗?它成功引起了我的注意,因为按照我的想法,如果是从拼图里拿出一部分拼成一个完成图片的话,那么最左边拿出来的图片,应该是从(0,0),(0,58),但是我们看到的是(1,0),(1,58),y值还是比较符合我们的预期的,第一部分从0开始,高58,第二部分从58开始。但是x值有点问题,按照1作为起点,那第二个应该是11,因为宽度是10,这是确定的,我们找找看

It is 13. Is there an extra pixel in front of each small block? According to this, it should also be 12. In this way, we continue to find the rest. Through analysis, we find that +12 for each small block is used as the starting point for the next small block. In this case, one pixel is removed from the left and right, isn't the width 10? And each small piece is 12, 26 is 312, which is similar to the size of the puzzle we have seen, indicating that our analysis is correct. According to the coordinates provided in the element, take the size of the width as 10. Next, analyze the meaning of these coordinates.

Coordinate analysis

Let’s analyze the screenshots from Figure 9 to Figure 12. First of all, let’s talk about Figure 9. I originally thought that its x and y should be 0. Even if it is not 0, it should be the numbers. The result y is 58. This is the second half of the picture. The area is gone, x is 157, and the running midfield is gone. In Figure 11, your x should be around 300, and y should be above 100. The result is 0. In the first half, x is 205. After the midfield, it is still far from the goalkeeper. What the hell is this? However, we found that Figure 9 is the first in the element, and Figure 11 is the last in the element. The y values ​​in front of the combined coordinates are all 58, and the y values ​​in the back are all 0, which is in line with the lower half of our first half. The idea of ​​the paragraph is reversed, and then you look at the elements on the right side of Figure 9/left side of Figure 11, and you will find that the order is the same as the order of the divs in the element. Almost there.

To sum up: the final picture is to cut out the puzzle, namely Figure 4, according to x=157, y=58, w=10, h=58, and place it in the first position of the upper part, x=145, y=58 , w=10, h=58 are cut out and placed in the second position of the upper half, next to the first one, and so on, to form a whole picture.


This is what I spelled out, um, very good, very good boy. But there seems to be something wrong, the gap. Take a closer look at web page elements

It turns out that one is fullbg and the other is cutbg. The name is very meaningful. That's good. Let's spell cutbg and see.


Right this time. Now the question becomes how to calculate the gap position

Notch position

I think there may be a way to calculate the different positions of the two pictures. Du Niang will send it, and then I get the python actual combat === Compare the difference between the two pictures with python, and then I found the interface of ImageChops.difference. As a result, you all know Yes, inaccurate, why pinch? Look carefully at the two assembled pictures, except for the gap, there are other places that are different. Seeing the shadow behind the notch in Figure 16 casts a shadow on my heart. When I look at other pictures, they are basically similar. What should I do? This can be said later, if it is in the front, then it will be counted in the shadow. It would be great if there was a tolerance for this comparison. I used to have this when I used the button wizard. Isn't this smart? Since it is a comparison pixel, I can just take the pixel and compare it, and I don't use == for it, but give it a range. If the color difference is within this range, it will be the same. Isn't there a tolerance? This gap is generally very obvious, and the shadow and background are very blurred, which should be feasible. The idea is to get the width and height of the picture, and then traverse and compare it pixel by pixel.

Chromatic aberration

How is this color difference determined? One way is to debug, which is more troublesome, and another way is to obtain multiple pictures, full pictures and defect pictures, and then use the color picking tool to take the color value of the corresponding position to determine an approximate range. The distance is determined, the next step is to move

selenium simulate mobile

The simulation operation of selenium is introduced a lot on the Internet, here we just need to confirm which interfaces are needed. ActionChains method:

  • movetoelement(to_element) – move the mouse to an element
  • clickandhold(on_element =None) - click the left mouse button, do not release
  • movebyoffset(xoffset, yoffset) – move the mouse from the current position to a certain coordinate
  • release(on_element = None) – release the left mouse button on an element
  • perform() –  perform the operation , remember this is very important, after calling the above method, you must execute the perform to actually execute

I will not describe the operation of selenium in detail. The simple usage is used here.

The principle analysis is over. This time, the code must be posted, otherwise many people may not be able to complete it, which is also conducive to everyone's understanding.

( Due to the limited space, the following is part of the code. For the complete code , please pay attention to the public account " Meow Dance Life " and reply to " 8419 " to get it )

# -*- coding: utf-8 -*-

import random

import time, re

from selenium import webdriver

from selenium.common.exceptions import TimeoutException

from selenium.webdriver.common.by import By

from selenium.webdriver.support.wait import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.common.action_chains import ActionChains

from PIL import Image

import requests

from io import BytesIO

class HuXiu(object):

def __init__(self):

chrome_option = webdriver.ChromeOptions()

# chrome_option.set_headless()

self.driver = webdriver.Chrome(executable_path=r"/usr1/webdrivers/chromedriver", chrome_options=chrome_option)

self.driver.set_window_size(1440, 900)

def visit_index(self):

self.driver.get("https://www.huxiu.com/")

WebDriverWait(self.driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//*[@class="js-register"]')))

reg_element = self.driver.find_element_by_xpath('//*[@class="js-register"]')

reg_element.click()

WebDriverWait(self.driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_slider_knob gt_show"]')))

# Enter the simulation drag process

self.analog_drag()

def analog_drag(self):

#Mouse the mouse to the drag button to display the drag image

element = self.driver.find_element_by_xpath('//div[@class="gt_slider_knob gt_show"]')

ActionChains(self.driver).move_to_element(element).perform()

time.sleep(3)

# Refresh the extreme test picture

element = self.driver.find_element_by_xpath('//a[@class="gt_refresh_button"]')

element.click()

time.sleep(1)

# Get a list of image addresses and location coordinates

cut_image_url, cut_location = self.get_image_url('//div[@class="gt_cut_bg_slice"]')

full_image_url, full_location = self.get_image_url('//div[@class="gt_cut_fullbg_slice"]')

# stitch pictures according to coordinates

cut_image = self.mosaic_image(cut_image_url, cut_location)

full_image = self.mosaic_image(full_image_url, full_location)

# Save the picture for easy viewing

cut_image.save("cut.jpg")

full_image.save("full.jpg")

# Calculate distance from two images

distance = self.get_offset_distance(cut_image, full_image)

# start moving

self.start_move(distance)

# if there is an error

try:

WebDriverWait(self.driver, 5, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_ajax_tip gt_error"]')))

print("Authentication failed")

return

except TimeoutException as e:

pass

# Determine whether the verification is successful

try:

WebDriverWait(self.driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_ajax_tip gt_success"]')))

except TimeoutException:

print("again times")

time.sleep(5)

# recursively execute drag after failure

self.analog_drag()

else:

# Enter the phone number after success and send the verification code

self.register()

# Get a list of pictures and locations

def get_image_url(self, xpath):

link = re.compile('background-image: url\("(.*?)"\); background-position: (.*?)px (.*?)px;')

elements = self.driver.find_elements_by_xpath(xpath)

image_url = None

location = list()

for element in elements:

style = element.get_attribute("style")

groups = link.search(style)

url = groups[1]

x_pos = groups[2]

y_pos = groups[3]

location.append((int(x_pos), int(y_pos)))

image_url = url

return image_url, location

(partial code)

For this movebyoffset, my previous y value was also random [-5,5]. I think this simulation will be more realistic, and it will always shake up and down. The result is that this consideration is too human, and the recognition rate is very low. I changed a lot of ranges, bigger and smaller, and the result did not shift in the end, and the recognition rate was extremely high. TMD thought it was too human to recognize it, and I was also drunk. Finally, let's post the execution effect.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324896644&siteId=291194637