本篇博客分享关于我在爬虫中如何解决弹窗,以及解决验证码的一种思路,仅作为参考,不同网站和不同验证码可能不能如法炮制,如果不能完全实现,请原谅! 时间:
2020年8月
如果看完有收获, 喜欢的话,记得关注,收藏一波哦!
爬虫解决弹窗:
弹窗本来是用来警告或者提示信息, 也可以起到反爬的作用, 而对于一个爬虫工作人员来说, 我们还是要解决这个弹窗问题。 弹窗的实质也就是网页的js脚本, 有些弹窗他是一次性的, 作为检测你是否是第一次登入, 这样的弹窗你爬虫之前先进去一次就可以搞定, 其他的弹窗的话,还是得看一下网页源码, 对症下药。 而一般弹窗会存放到第一个节点
script
里面 ,也有特殊情况。读懂网页源码,才是解决的最好办法。
常见alert
式弹出框
alert(message)
显示警告或其他信息,用于通知用户,下方只有一个【确认】按钮。confirm(message)
询问是否继续某种操作等功能,下方有【确认】和【取消】两种按钮prompt(text, defaultText)
,需要输入一些信息,比如用户密码等,下方会有【确认】和【取消】按扭
新版本 selenium
中语法规则已经改掉, 现在为 driver.switch_to.alert.accept()
- 这类弹窗可以使用
selenium工具
的 switch_to.alert() 方式 去处理 具体如下:
关于switch_to.alert( ) 参数
名称 | 用法 |
---|---|
accept() | 点击Alert的【确认】按钮 |
authenticate(username,password) | 给需要验证的Alert发送账号和密码,默认点击OK |
dismiss() | 点击Alert的【取消】按钮 |
send_keys(keysToSend) | 在Alert的输入框输入信息 |
text | 获取Alert上的文言信息 |
switch_to.alert | 切换到Alert |
- 这里用js代码生成一个弹窗, 使用该函数试一试流程, 是如何解决的!
url = 'http://www.baidu.com'
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(url)
# driver.execute_script("window.alert('这是一个测试Alert弹窗');")
driver.execute_script("window.confirm('这也是一个测试窗口')")
time.sleep(2)
a = driver.switch_to.alert.text # 捕获弹窗 获得文本信息
print(a)
driver.switch_to.alert.dismiss() # 捕获弹窗,点击取消
time.sleep(2)
driver.quit()
如果不是传统的alert弹窗类型
大致意思就是, 你用前面的方式行不通了, 你再来试试用这些方法。
非传统alert式
弹出框的处理
- 弹出框位于
div
层,跟平常定位方法一样 - 弹出框是嵌套的
iframe
层,需要切换iframe - 弹出框位于嵌套的
handle
,需要切换窗口
这里给出第一种方式:
from selenium import webdriver
import time
url = 'http://www.baidu.com'
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(url)
time.sleep(1)
driver.find_driver.find_element_by_xpath("弹窗点击按钮").click()
# 另外二种, 使用 browser.switch_to.frame('main') 先切换
# 或者 browser.execute_script('window.open()') # 新建选项卡 功能
# browser.switch_to.window(browser.window_handles[1])
最后一个办法:
老铁们, 实在解决不了的, 直接手动把弹窗关掉吧, 但是如果是我的话, 我得花点时间研究一下, 毕竟能解决一个新的问题,对我收获很大! 哈哈, 这里皮一下!
爬虫解决验证码:
验证码也是反爬的一个鼻祖吧, 最开始就是用验证码的, 然后现在五花八门, 滑动的, 滑动卡位的, 猜数的, 猜文字的, 越来越欺负人了, 只不过为了模拟登入而已, 真考验人, 这里我用的方式是tesseract, 实话说, 这个成功率不是很高, 配置也很麻烦, 后期需要训练数集, 才能达到识别率高的效果, 不过还是分享一下。
关于tesseract安装配置
- 在python中, 需要安装 pytesseract 库
- 基础安装我就不讲了, 下好这个然后安装就行了。
-
下载中文识别包, 放到database文件夹里面。
-
环境变量 这个可以去设置, 但是我没有设置, 我是直接在使用的时候指定了工具和工具包的位置!
-
pytesseract中更改 tesseract_cmd 的路径:
一般来说, 对于验证码,使用tesseract我们至少来说要做三步。
1: 爬验证码,保存, 截取验证码
比如,我们要登入这个网站,要获取这个验证码,思路如下:
from PIL import Image
import pytesseract
import tesserocr
from selenium import webdriver
import time
url = 'https://authserver.nju.edu.cn/authserver/login'
driver = webdriver.Chrome()
driver.get(url)
driver.maximize_window() # 最大化窗口
time.sleep(2)
# 切换验证码登入 因为进去是显示账号登入
driver.find_element_by_xpath('//*[@id="dyLogin"]').click()
time.sleep(1)
# 图片节点 拿下来
img = driver.find_element_by_xpath('//*[@id="dynamicCodeChangeCaptcha"]')
location = img.location
size = img.size
# 不同图片 参数不一样的,这里我实验了几次,得到如下参数
left = location['x'] + 250
top = location['y'] + 90
right = left + size['width'] + 100
bottom = top + size['height'] + 20
driver.save_screenshot('valicode.png')
page_snap_obj = Image.open('valicode.png')
image_obj = page_snap_obj.crop((left, top, right, bottom))
image_obj.show()
image_obj.save("valicode.png")
driver.quit()
2: 图片灰度转换, 二值化, 去噪点
经过上面一步, 我们拿到了一张只包含验证码的图片, 但是需要进行进一步处理。
image_obj = Image.open('valicode.png')
img = image_obj.convert("L") # 转灰度图
pixdata = img.load()
w, h = img.size
threshold = 120 # 这个120 也是自己实践得到, 不是每次都是120
# 遍历所有像素,大于阈值的为黑色
for y in range(h):
for x in range(w):
if pixdata[x, y] < threshold:
pixdata[x, y] = 0
else:
pixdata[x, y] = 255
data = img.getdata()
w, h = img.size
black_point = 0
for x in range(1, w - 1):
for y in range(1, h - 1):
mid_pixel = data[w * y + x]
if mid_pixel < 50:
top_pixel = data[w * (y - 1) + x]
left_pixel = data[w * y + (x - 1)]
down_pixel = data[w * (y + 1) + x]
right_pixel = data[w * y + (x + 1)]
if top_pixel < 10:
black_point += 1
if left_pixel < 10:
black_point += 1
if down_pixel < 10:
black_point += 1
if right_pixel < 10:
black_point += 1
if black_point < 1:
img.putpixel((x, y), 255)
black_point = 0
img.show()
img.convert('L')
img.save('valicode.png')
然后就得到了一张这样的图片
3: 使用pytesseract进行图片的识别
img = Image.open('valicode.png')
img.show()
# 这个是tesseract路径
pytesseract.pytesseract.tesseract_cmd = 'D:/Tesseract-OCR/tesseract.exe'
# 这个是识别包路径
dir_config = '--tessdata-dir "D:/Tesseract-OCR/tessdata"'
# 下面如果识别的中文, 可以指定 lang = "chi_sim"
result = pytesseract.image_to_string(img, config=dir_config)
print(result)
嘿嘿, 很抱歉, 我没有识别出来, 哈哈哈哈哈哈。操作了一整晚,为什么没成功识别,我也很纳闷, 我觉得还是图片没有处理好, 可能还需要去一下噪点什么的, 总之,思路大概是这样的, 如果有懂行的,知道怎么解决的,欢迎评论区告诉我你的方法, 多谢!
其他方法:
花钱找打码平台 或者 手动输入验证码 ! tesseract的识别率没有那么高, 需要训练数集。
转载:https://blog.csdn.net/qq_45906219/article/details/107824777