用 python 的 selenium 访问 https://www.huxiu.com/
自动通过验证码
# -*- coding: utf-8 -*- # 斌彬电脑 # @Time : 2018/9/11 0011 4:38 ''' 滑动验证码之 极验 验证码 https://www.huxiu.com/ ''' from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.chrome.options import Options from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.webdriver import ActionChains # 动作链 import requests,re from PIL import Image from io import BytesIO # 不写入磁盘,显示图片文件 import time, random class JiYan(): def __init__(self): # 浏览器参数 options = Options() options.add_argument('--window-size=1366,768') self.dri = webdriver.Chrome(chrome_options=options) self.btn = WebDriverWait(self.dri, 10) # 访问页面 def to_request(self): self.dri.get('https://www.huxiu.com/') # 找到登录按钮 self.btn.until(EC.presence_of_element_located((By.XPATH, '//a[@class="js-login"]'))).click() # 找到输入框 f = self.btn.until(EC.presence_of_element_located((By.XPATH, '//input[@id="sms_username"]'))) # 输入内容 f.send_keys('13605838837') # 获取验证码图片 def get_img(self): # # 没有缺陷的图片 g_img = self.dri.find_elements_by_xpath( '//div[@class="gt_cut_fullbg gt_show"]/div') # print(len(g_img)) # 拿到图片的 url 和 偏移量 style_list = [i.get_attribute('style') for i in g_img] # print(style_list) # 匹配到连接 因为每个连接是一样的,所以只要匹配到一个就行 # 验证码的图片连接 img_url = re.search(r'url("(.*?)");',style_list[0]).group(1) # print(img_url) # 图片二进制的值 img_con = requests.get(img_url).content # 得到完整的验证码 get_po = self.get_img2(style_list, img_con) # get_po.show() # 显示出来 # 有缺陷的图片 bg_g_img = self.dri.find_elements_by_xpath( '//div[@class="gt_cut_bg gt_show"]/div') # 拿到图片的 url 和 偏移量 style_list = [i.get_attribute('style') for i in bg_g_img] # 匹配到连接 因为每个连接是一样的,所以只要匹配到一个就行 # 验证码的图片连接 img_url2 = re.search(r'url("(.*?)");',style_list[0]).group(1) # print(img_url) # 图片二进制的值 img_con = requests.get(img_url2).content # 得到完整的验证码 bg_get_po = self.get_img2(style_list, img_con) # bg_get_po.show() # 调用比较函数 return self.contrast(get_po, bg_get_po) # 拼接验证码 def get_img2(self,style_list,image): # 拿到偏移量 # ?可能有的时候没有 po_list = [re.findall(r'background-position: -(.*?)px -?(.*?)px;', i) for i in style_list] # print(po_list) # 新建图片 im_new = Image.new('RGB',(260,116)) im = Image.open(BytesIO(image)) up = 0 dn = 0 for i in po_list[:26]: # 前26个,上半部分 # print(i) # 左上角x, y 右上角 x, y cro = im.crop((int(i[0][0]),58, int(i[0][0])+10,116)) # 拿到偏移量,进行裁剪 # up 为粘贴位置 im_new.paste(cro,(up,0)) # 把裁剪下的图片粘贴到新建空白图片上,得到张新图 up += 10 # 每张小图的宽度是10px, for i in po_list[26:]: # 后26个,下半部分 # print(i) # 左上角x, y 右上角 x, y cro = im.crop((int(i[0][0]),0, int(i[0][0])+10,58)) # 拿到偏移量,进行裁剪 # up 为粘贴位置 im_new.paste(cro,(dn,58)) # 把裁剪下的图片粘贴到新建空白图片上,得到张新图 dn += 10 # 每张小图的宽度是10px, return im_new # 有缺陷的图片与无缺陷的图片对比,得到距离值 def contrast(self,cut,no_cut): def contrast_pi(px1,px2): for i in range(3): # 像素点的差达到指定值(RGB), if abs(px1[i] - px2[i]) > 50: return False for i in range(260): # 宽度像素点 for j in range(116): # 高度像素点 px1 = cut.getpixel((i,j)) # 取得第一张每个像素点的值 px2 = no_cut.getpixel((i,j)) # 取得第二张每个像素点的值 if contrast_pi(px1,px2) is False : # 比较两张图片同一位置的像素点的值 # 如果找到两张图片的像素差值达到要求,就返回 i ,得到滑动的距离 return i # 控制浏览器滑动 def slide(self, distance): # 可见滑动 dis = self.btn.until(EC.visibility_of_element_located((By.XPATH, '//div[@class="gt_slider_knob gt_show"]'))) # 点出不放 ActionChains(self.dri).click_and_hold(dis).perform() time.sleep(0.5) # 移动 传入距离的值,X,Y # ActionChains(self.dri).move_by_offset(distance-5, 0).perform() for i in self.track(distance-5): ActionChains(self.dri).move_by_offset(i, 0).perform() time.sleep(0.6) # 释放- ActionChains(self.dri).release(dis).perform() # 模拟人拖动 def track(self,distance): t = 0.2 # 时间 current = 0 # 当前 mid = distance * 3/5 speed = 0 # 速度 move_distance_list = [] while current < distance: # 当前小于距离时, if current < mid: # 如果当前小于中间距离 a = 2 # 加速度 else:a = -5 move_distance = speed*t+0.5*a*t*t move_distance_list.append(round( move_distance )) # 整数添加进列表 speed += (a*t) current += move_distance offset = sum(move_distance_list) - distance if offset > 0: move_distance_list.extend([-1]*offset) elif offset < 0: move_distance_list.extend( [1]*abs(offset) ) # - 左移, 0 停止 右移 move_distance_list.extend([-1,-1,-1,-1,-1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,-1.-1.-1.]) return move_distance_list # 让类可以像函数一样调用 h() 执行类 #def __call__(self, *args, **kwargs): h = JiYan() h.to_request() time.sleep(2) distance = h.get_img() h.slide(distance)
在 linux 下
python 的文字识别库(视觉系统)
进行安装
(视觉系统)要与 pyghon 交互,所以还要安装pytesseract
d