Python-解决每次请求响应的验证码都不一样的情况


还是书接上回,一开始只考虑了怎么破解验证码,而从没想过怎么获取,以为还是那种普通的图片,结果每次刷新返回的都不一样,而且页面源码中也没记录(可能有,但去找的话很耗时间),所以记录一下;

在网上查找了解决办法:

  1. 截取验证码(没考虑),先不说别的,截取的分辨率就会降低,还有就是我的是svg,而且我提前写的解析验证码的代码,是根据svg文件内容解析的,所以根本没考虑
    1. 100%解析svg-captcha验证码
  2. 模拟键盘右键下载(尝试过)
  3. 分析登陆,分析js(这需要一定的前端基础,还有就是不适合所有场景)推荐文章:
    1. 爬虫模拟登录学校教务系统
  4. seleniumwire(推荐)

模拟键盘右键下载

不做过多的介绍,为什么没选择这个呢?第一点也是最重要的一点就是因为,它是模拟键盘,所以自然在wind和linux系统上要写不一样的代码,要才用不同的第三方库,而不能实现跨平台,第二点就是时间,所需要的时间超过预期,毕竟调出系统的文件管理就要一定的时间。

所以下面我直接只展示在wind上怎么操作,linux将采用:‘pynput“依赖,大家可自行测试。直接看代码:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from bs4 import BeautifulSoup
import re
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import win32api
import win32con
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import pyautogui
import os

VK_CODE = {'enter': 0x0D, 'down_arrow': 0x28}


# 定义按下键盘事件
def keyDown(keyName):
    win32api.keybd_event(VK_CODE[keyName], 0, 0, 0)


# 定义松开键盘事件
def keyUp(keyName):
    win32api.keybd_event(VK_CODE[keyName], 0, win32con.KEYEVENTF_KEYUP, 0)


chrome_options = Options()
chrome_options.add_argument('‐‐headless')
chrome_options.add_argument('‐‐disable‐gpu')
path = r'C:\Program Files\Google\Chrome\Application\chrome.exe'
chrome_options.binary_location = path
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get(
    "https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E7%BE%8E%E5%9B%BE%E7%BD%91&step_word=&hs=2&pn=1&spn=0&di=13200&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=113014737%2C3445157660&os=2351244306%2C2367448695&simid=3050896469%2C3730470527&adpicid=0&lpn=0&ln=362&fr=&fmq=1570618921319_R&fm=&ic=undefined&s=undefined&hd=undefined&latest=undefined&copyright=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=http%3A%2F%2Fgss0.baidu.com%2F-vo3dSag_xI4khGko9WTAnF6hhy%2Fzhidao%2Fpic%2Fitem%2F0df431adcbef7609968039362cdda3cc7dd99e94.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Fooo_z%26e3Bp7xt_z%26e3Bv54_z%26e3BvgAzdH3Fetjof-8nbml9nnclam-8nbml9nnclamdbdd_z%26e3Bip4s&gsm=&rpstart=0&rpnum=0&islist=&querylist=&force=undefined")
image = driver.find_element(by=By.XPATH, value="/html/body/div[1]/div[2]/div/div[1]/img")
# 定位图片所在的元素
action = ActionChains(driver).move_to_element(image)
# ActionChains(driver).context_click(image).perform()
action.context_click(image).perform()  # 在图片元素上执行右键单击操作
time.sleep(1)  # 防止图片未加载出来
win32api.keybd_event(86, 0, 0, 0)  # 调用按下键盘函数,为函数传入参数“86”,也就是“v”
win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0)  # 松开键盘“V”
time.sleep(5)  # 等待一秒

keyDown('enter')  # 按下“确认”按钮
keyUp('enter')  # 松开确认按钮
time.sleep(1)  # 等待一秒
print("图片下载完成")
# 获取当前工作目录
current_directory = os.getcwd()
print(current_directory)

# 生成保存路径
filename = 'image.jpg'
save_path = os.path.join(current_directory, filename)

# 移动下载的图片到当前目录
os.rename('C:/Users/co_wb_junjie_qiu/Downloads/73a50f338271ac555a5aa87465687637287dc3ed27641-VQpYE3_fw658.webp',
          save_path)
print("图片下载完成,保存路径为:", save_path)


# pyinstaller --F main.py --add-binary "D:/tools/pyJDK/envs/pytest/DLLs*:."  --osx-bundle-identifier=com.example.yourapp main.py
# wget https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tar.xz

使用此方法,必须在保存完之后调整保存路径

使用seleniumwire

seleniumwire可以理解成是对selenium的增强,婉如mybatis和mybatisplus,因为selenium无法获取请求页面的响应结果

from seleniumwire import webdriver
from selenium.webdriver.common.by import By
import time

driver = webdriver.Chrome()

driver.get('需要请求的路径')
son_div1 = driver.find_element(by=By.XPATH, value="//div[@class='user_area']/a[1]")
time.sleep(1)
son_div1.click()
response = None
for request in driver.requests:
    print(request.url)
    # 请求图片的url,获取这个请求的数据
    if request.url.startswith("图片路径"):
        print(request.url)
        response = request.response
        break

if response:
    response_body = response.body
    print(response_body)
    with open('image.svg', 'wb') as file:
        file.write(response_body)
        print("图片下载完成")

time.sleep(20)

不知道为什么,我在网上没有搜到这种使用方式,可能是我搜索的方式有问题吧,知道我直接拿seleniumwire去搜索才隐隐约约出现这种结果

寄语

珍惜眼前!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值