数据采集: selenium 自动翻页接口调用时的验证码处理
写在前面
- 工作中遇到,简单整理
- 理解不足小伙伴帮忙指正
对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》
在数据采集
的过程中,有部分页面会在接口调用到一定次数
之后,每次获取数据调用接口之后,弹出一个验证码的校验,作为一种反爬措施
,对于这种接口调用验证码,一般情况下,是只要请求就跳转,有部分页面是随机的,比如页面中有好多搜索框,可能每个搜索框的change 事件都会发生一次接口调用,这个时候使用 selenium 自动化提提取数据,会导致处理的页面不是想要的的页面,所以对于这种验证码的处理,我们需要在页面任意位置,提供一个检测跳转验证码验证页面的方法,同时对验证码做校验处理。
下面为一个 Demo
def cap(driver):"""@Time : 2023/08/29 03:38:33@Author : liruilonger@gmail.com@Version : 1.0@Desc : 验证码处理Args:driverReturns:void"""import ddddocrocr = ddddocr.DdddOcr()time.sleep(3)while len(driver.find_elements(By.XPATH,"//h1[contains(text(),'输入验证码刷新') ] " )) > 0:element = driver.find_element(By.XPATH, "//img[ @id='vcodeimg' ]")# 清空验证码数据driver.execute_script("arguments[0].value = ''", element)#定位元素并获取截图文件: element.screenshot("element.png")with open("element.png", "rb") as f:image_bytes = f.read()#image_bytes = BytesIO(base64.b64decode(screenshot))text = ocr.classification(image_bytes)if len(text) >4:text = text[1:5]driver.find_element(By.XPATH, "//input[@id='vcode']").send_keys(text)time.sleep(3)driver.find_element(By.XPATH, "//input[@class='isOK']").click()time.sleep(3)# 验证失败重新验证if len(driver.find_elements(By.XPATH,"//h1[contains(text(),'输入验证码刷新') ] " )) > 0:driver.get("https://icp.chinaz.com/captcha")
在实际的编写中需要注意的地方:
- 获取验证码图片的方式,是通过对元素截图,还是对照片路径请求下载获取,需要注意有些验证码图片,在通过
requests
库下载图片时,每次调用都是不同的图片,所以只能使用截图的方式 - 验证码识别的方式,可以考虑使用
ocr
或者深度学习模型,或者一些商业接口,上面使用的pip install ddddocr
- 对于识别不准的情况,可以考虑做一些后期的约束处理,比如上面的验证码,4位数字,但是在第一位会出现一个干扰字符,ocr 偶尔会识别为字符,需要做切割处理。
- 进行识别的时机,以及识别后的处理,对于如何开始识别,可以通过关键字来进行判断,放到入口处,对于识别后验证失败的处理也需要考虑,上面的页面在识别验证成功会进行跳转,错了不发生跳转
- 对于错误的情况,可以使用死循环的,重新请求,获取新的验证码,直到识别验证成功。
下面为一个数据采集的实际脚本中的使用。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : icp_reptile.py
@Time : 2023/08/23 23:07:46
@Author : Li Ruilong
@Version : 1.0
@Contact : liruilonger@gmail.com
@Desc : 验证码版本
"""# here put the import libfrom selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import re
import pandas as pd
import csv
import sys
import os
import json
import requests
import ddddocr
from io import BytesIO
import base64
import pytesseract
from PIL import Imagea_name = ['河北']
ocr = ddddocr.DdddOcr()"""
自动登陆,需要提前保存登陆cookie 信息
"""
driver = webdriver.Chrome()
with open('C:\\Users\山河已无恙\\Documents\GitHub\\reptile_demo\\demo\\cookie_vip.json', 'r', encoding='u8') as f:cookies = json.load(f)driver.get('https://icp.chinaz.com/provinces')
for cookie in cookies:driver.add_cookie(cookie)driver.get('https://icp.chinaz.com/provinces')wait = WebDriverWait(driver, 30)## 查询条件准备"""
查询条件准备
"""#wait.until(EC.presence_of_element_located((By.XPATH, "//span[ @title='chinaz_7052291' ]")))def cap(driver):"""@Time : 2023/08/29 03:38:33@Author : liruilonger@gmail.com@Version : 1.0@Desc : 验证码处理Args:Returns:void"""time.sleep(3)while len(driver.find_elements(By.XPATH,"//h1[contains(text(),'输入验证码刷新') ] " )) > 0:element = driver.find_element(By.XPATH, "//img[ @id='vcodeimg' ]")# 清空验证码数据driver.execute_script("arguments[0].value = ''", element)#定位元素并获取截图文件: element.screenshot("element.png")with open("element.png", "rb") as f:image_bytes = f.read()#image_bytes = BytesIO(base64.b64decode(screenshot))text = ocr.classification(image_bytes)if len(text) >4:text = text[1:5]driver.find_element(By.XPATH, "//input[@id='vcode']").send_keys(text)time.sleep(3)driver.find_element(By.XPATH, "//input[@class='isOK']").click()time.sleep(3)if len(driver.find_elements(By.XPATH,"//h1[contains(text(),'输入验证码刷新') ] " )) > 0:driver.get("https://icp.chinaz.com/captcha")time.sleep(5)
# 触发验证码处理
all_butt_cap = driver.find_element(By.XPATH,"//h1[contains(text(),'输入验证码刷新') ] " )# 处理验证码的情况cap(driver)time.sleep(5)### 查询条件准备# 备案时间
all_butt = driver.find_element(By.XPATH,"//div/a[contains(@href,'all') and @class='pr10' ] " )
driver.execute_script("arguments[0].click();", all_butt)
cap(driver)
# 单位性质
all_butt = driver.find_element(By.XPATH,"//div[contains(text(),'全部') and @class='MainCateW-cont SearChoese'] " )
driver.execute_script("arguments[0].click();", all_butt)
time.sleep(3)
cap(driver)
# 企业
all_butt = driver.find_element(By.XPATH,"//a[contains(text(),'企业') and @val='企业' ]" )
driver.execute_script("arguments[0].click();", all_butt)
time.sleep(2)cap(driver)
# 状态
all_butt = driver.find_element(By.XPATH,"//div[contains(text(),'全部') and @id='webStatus_txt' and @class='MainCateW-cont SearChoese w90'] " )driver.execute_script("arguments[0].click();", all_butt)
time.sleep(2)
# 已开通
all_butt = driver.find_element(By.XPATH,"//a[contains(text(),'已开通') and @val='1' ]" )driver.execute_script("arguments[0].click();", all_butt)
time.sleep(2)
cap(driver)# 地区
all_butt = driver.find_element(By.XPATH,"//strong[contains(text(),'地区:') and @class='CateTit' ]" )
next_element = all_butt.find_element(By.XPATH,"following-sibling::*[1]")
driver.execute_script("arguments[0].click();", next_element)
time.sleep(2)def area(p_name,driver,p_data):"""@Time : 2023/08/24 04:24:50@Author : liruilonger@gmail.com@Version : 1.0@Desc : 备案数据获取Args:Returns:void"""all_butt = driver.find_element(By.XPATH,"//a[contains(text(),'"+p_name+"') ]" )driver.execute_script("arguments[0].click();", all_butt)#all_butt.click()time.sleep(2)# 页数太对分盟市处理,后面的数据没办法直接处理all_butt = driver.find_element(By.XPATH,"//div[contains(text(),'全部') and @id='addrctxt' ]" )time.sleep(2)driver.execute_script("arguments[0].click();", all_butt)all_ui = driver.find_element(By.XPATH,"//ul[ @id='addrclst'] " )citys = all_ui.find_elements(By.TAG_NAME,'a')for city in citys:try:c_n =city.textexcept:print("页面异常")continueif c_n == '全部':continueprint("处理市:",c_n)time.sleep(2)driver.execute_script("arguments[0].click();", city)time.sleep(5)# 验证码处理cap(driver)time.sleep(5)# 查询cap(driver)# 选择全部all_butt = driver.find_element(By.XPATH,"//div/a[contains(@href,'all') and @val='all' ] " )driver.execute_script("arguments[0].click();", all_butt)time.sleep(5)cap(driver)#all_butt = driver.find_element(By.XPATH,"//input[ @type='button' and @id='btn_search' and @value='点击搜索'] " )#driver.execute_script("arguments[0].click();", all_butt)#time.sleep(4)#cap(driver)time.sleep(10)def all_break(driver):if len(driver.find_elements(By.XPATH,"//span[contains(text(),'页,到第') and @class='col-gray02'] " )) == 0:all_butt = driver.find_element(By.XPATH,"//div/a[contains(@href,'all') and @val='all' ] " )driver.execute_script("arguments[0].click();", all_butt)time.sleep(5)cap(driver)time.sleep(10)#all_break(driver)# 总页数获取page_butt = driver.find_element(By.XPATH,"//span[contains(text(),'页,到第') and @class='col-gray02'] " )page_c = int(re.search(r'\d+', page_butt.text).group())# 盟市页数太多分时间段处理 # 当前页数据处理tbody = driver.find_element(By.XPATH,"//tbody[ @class='result_table' and @id='result_table' ]")rows = tbody.find_elements(By.TAG_NAME,'tr')for row in rows:# 获取当前行中的所有单元格cells = row.find_elements(By.TAG_NAME, "td")# 打印单元格数据data = {}data['域名']=cells[0].textdata['主办单位名称']=cells[1].textdata['网站首页网址']=cells[5].textp_data.append(data)# 其他页数据处理 if page_c >= 101:page_c = 101 for page_i in range(1,page_c):try:print(f"{c_n} :处理页数",page_i)nextPage = driver.find_element(By.XPATH,"//a[ @title='下一页' and @id='nextPage' ]")driver.execute_script("arguments[0].click();", nextPage)time.sleep(3)cap(driver)all_break(driver)cap(driver)#nextPage.click()time.sleep(6)tbody = driver.find_element(By.XPATH,"//tbody[ @class='result_table' and @id='result_table' ]")rows = tbody.find_elements(By.TAG_NAME,'tr')print(tbody.text)for row in rows:# 获取当前行中的所有单元格cells = row.find_elements(By.TAG_NAME, "td")# 打印单元格数据data = {}data['域名']=cells[0].textdata['主办单位名称']=cells[1].textdata['网站首页网址']=cells[5].textp_data.append(data)time.sleep(6)except:print(f"第 { page_i} 页发生了异常,跳过了")pass finally: fieldnames = ['域名', '主办单位名称', '网站首页网址']with open('省份_'+a+'_'+"ICP"+'.csv', 'w', newline='',encoding='utf-8') as file:writer = csv.DictWriter(file, fieldnames=fieldnames)writer.writeheader() # 写入列名writer.writerows(p_data) # 写入字典数据print("数据已保存为CSV文件",' CDN_M_省份_'+a+'_'+'ICP'+'.csv') return p_data if __name__ == '__main__':for a in a_name:p_data= []try:p_data = area(a,driver,p_data)except:continuepassfinally:fieldnames = ['域名', '主办单位名称', '网站首页网址']with open('省份_'+a+'_'+"ICP"+'.csv', 'w', newline='',encoding='utf-8') as file:writer = csv.DictWriter(file, fieldnames=fieldnames)writer.writeheader() # 写入列名writer.writerows(p_data) # 写入字典数据print("数据已保存为CSV文件",' CDN_M_省份_'+a+'_'+'ICP'+'.csv') time.sleep(55555)
博文部分内容参考
© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 😃
© 2018-2023 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)
相关文章:
数据采集: selenium 自动翻页接口调用时的验证码处理
写在前面 工作中遇到,简单整理理解不足小伙伴帮忙指正 对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大…...
IDEA安装翻译插件
IDEA安装翻译插件 File->Settings->Plugins 在Marketplace中,找到Translation,点击Install 更换翻译引擎 勾选自动翻译文档 翻译 鼠标右击->点击Translate...
DBeaver使用
一、导出表结构 二、导出数据CSV 导出数据时DBeaver并没有导出表结构,所以表结构需要额外保存; 导入数据CSV 导入数据时会因外键、字段长度导致失败;...
Nougat:一种用于科学文档OCR的Transformer 模型
随着人工智能领域的不断进步,其子领域,包括自然语言处理,自然语言生成,计算机视觉等,由于其广泛的用例而迅速获得了大量的普及。光学字符识别(OCR)是计算机视觉中一个成熟且被广泛研究的领域。它有许多用途,…...
redis八股1
参考Redis连环60问(八股文背诵版) - 知乎 (zhihu.com) 1.是什么 本质上是一个key-val数据库,把整个数据库加载到内存中操作,定期通过异步操作把数据flush到硬盘持久化。因为纯内存操作,所以性能很出色,每秒可以超过10…...
人工智能基础-趋势-架构
在过去的几周里,我花了一些时间来了解生成式人工智能基础设施的前景。在这篇文章中,我的目标是清晰概述关键组成部分、新兴趋势,并重点介绍推动创新的早期行业参与者。我将解释基础模型、计算、框架、计算、编排和矢量数据库、微调、标签、合…...
Date日期工具类(数据库日期区间问题)
文章目录 前言DateUtils日期工具类总结 前言 在我们日常开发过程中,当涉及到处理日期和时间的操作时,字符串与Date日期类往往要经过相互转换,且在SQL语句的动态查询中,往往月份的格式不正确,SQL语句执行的效果是不同的…...
为什么需要 TIME_WAIT 状态
还是用一下上一篇文章画的图 TCP 的 11 个状态,每一个状态都缺一不可,自然 TIME_WAIT 状态被赋予的意义也是相当重要,咱们直接结论先行 上文我们提到 tcp 中,主动关闭的一边会进入 TIME_WAIT 状态, 另外 Tcp 中的有 …...
Linux——(第七章)文件权限管理
目录 一、基本介绍 二、文件/目录的所有者 1.查看文件的所有者 2.修改文件所有者 三、文件/目录的所在组 1.修改文件/目录所在组 2.修改用户所在组 四、权限的基本介绍 五、rwx权限详解 1.rwx作用到文件 2.rwx作用到目录 六、修改权限 一、基本介绍 在Linux中&…...
Scala在大数据领域的崛起:当前趋势和未来前景
文章首发地址 Scala在大数据领域有着广阔的前景和现状。以下是一些关键点: Scala是一种具有强大静态类型系统的多范式编程语言,它结合了面向对象编程和函数式编程的特性。这使得Scala非常适合处理大数据,因为它能够处理并发、高吞吐量和复杂…...
前端面试经典题--页面布局
题目 假设高度已知,请写出三栏布局,其中左、右栏宽度各为300px,中间自适应。 五种解决方式代码 浮动解决方式 绝对定位解决方式 flexbox解决方式 表格布局 网格布局 源代码 <!DOCTYPE html> <html lang"en"> <…...
【webrtc】接收/发送的rtp包、编解码的VCM包、CopyOnWriteBuffer
收到的rtp包RtpPacketReceived 经过RtpDepacketizer 解析后变为ParsedPayloadRtpPacketReceived 分配内存,执行memcpy拷贝:然后把 RtpPacketReceived 给到OnRtpPacket 传递:uint8_t* media_payload = media_packet.AllocatePayload(rtx_payload.size());RTC...
Bash常见快捷键
生活在 Bash Shell 中,熟记以下快捷键,将极大的提高你的命令行操作效率。 编辑命令 Ctrl a :移到命令行首Ctrl e :移到命令行尾Ctrl f :按字符前移(右向)Ctrl b :按字符后移&a…...
软件验收测试
1. 服务流程 验收测试 2. 服务内容 测试过程中,根据合同要求制定测试方案,验证工程项目是否满足用户需求,软件质量特性是否达到系统的要求。 3. 周期 10-15个工作日 4. 报告用途 可作为进行地方、省级、国家、部委项目的验收࿰…...
Java 与零拷贝
零拷贝是由操作系统实现的,使用 Java 中的零拷贝抽象类库在支持零拷贝的操作系统上运行才会实现零拷贝,如果在不支持零拷贝的操作系统上运行,并不会提供零拷贝的功能。 简述内核态和用户态 Linux 的体系结构分为内核态(内核空间…...
AI性能指标解析:误触率与错误率
简介:随着人工智能(AI)技术的不断发展,它越来越多地渗透到我们日常生活的各个方面。从个人助手到自动驾驶,从语音识别到图像识别,AI正不断地改变我们与世界的互动方式。但你有没有想过,如何准确…...
count(*) 和 count(1) 有什么区别?哪个性能最好?
哪种 count 性能最好? count() 是什么? count() 是一个聚合函数,函数的参数不仅可以是字段名,也可以是其他任意表达式,该函数的作用是统计符合查询条件的记录中,函数指定的参数不为 NULL 的记录由多少条。…...
橡胶密封件为什么会老化?
橡胶密封件以其优良的密封性能被广泛应用于各个行业。然而,随着时间的推移,这些橡胶密封件往往会恶化和老化。在这篇文章中,我们将探讨橡胶密封件老化的原因。 1,导致橡胶密封件老化的主要因素之一是暴露在阳光和紫外线(UV)辐射下…...
Uboot中bootargs以及bootcmd设置
Uboot命令 一、Uboot基础命令 查看帮助信息: uboot#help打印环境变量: uboot#printenv其他命令: uboot#help ? - 帮助命令,等同于 help base - 打印或设置地址偏移量 bdinfo - 打印板级信息结构 boot …...
冠达管理:减肥药概念再度爆发,常山药业两连板,翰宇药业等大涨
减肥药概念12日盘中再度拉升,到发稿,常山药业“20cm”涨停,翰宇药业涨超14%,德展健康涨停,金凯生科涨近9%,争气股份、普利制药、昊帆生物涨约5%,诺泰生物、圣诺生物、华森制药等涨超4%。 常山药…...
实现在外网SSH远程访问内网树莓派的详细教程
文章目录 如何在局域网外SSH远程访问连接到家里的树莓派?如何通过 SSH 连接到树莓派步骤1. 在 Raspberry Pi 上启用 SSH步骤2. 查找树莓派的 IP 地址步骤3. SSH 到你的树莓派步骤 4. 在任何地点访问家中的树莓派4.1 安装 Cpolar4.2 cpolar进行token认证4.3 配置cpol…...
Pytorch框架详解
文章目录 引言1. 安装与配置1.1 如何安装PyTorch1.2 验证安装 2. 基础概念2.1 张量(Tensors)2.1.1 张量的基本特性2.1.2 创建张量2.1.3 张量操作 2.2 自动微分(Autograd)2.2.1 基本使用2.2.2 计算梯度2.2.3 停止追踪历史2.2.4 自定…...
2023年9月制造业NPDP产品经理国际认证报名来这错不了
产品经理国际资格认证NPDP是新产品开发方面的认证,集理论、方法与实践为一体的全方位的知识体系,为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会(PDMA)成立于1979年,是…...
linux(centos7)配置SSH免密登录
给三台机器配置主机名映射 在Windows系统中修改hosts文件,新增以下内容; 192.168.xxx.xxx bigdata_node1 192.168.xxx.xxx bigdata_node2 192.168.xxx.xxx bigdata_node33台Linux的/etc/hosts文件中,填入如下内容。 192.168.xxx.xxx bigda…...
cf 交互题
今天cf遇到了交互题,这个交互题的算法很很很简单,但是在交互上卡了,导致交上的代码都不算罚时。(更伤心了。 所以,现在写一下交互题的做法,印象深刻嘛。 交互题,就是跟机器进行交互。你代码运…...
成都瀚网科技有限公司:抖音怎么绑定抖音小店才好?
抖音是一款非常流行的短视频应用,为用户提供了一个展示才华、分享生活的平台。在抖音上,用户可以通过绑定抖音商店来销售自己的产品或服务,从而实现商业变现。那么,抖音如何绑定抖音商店呢? 1、抖音如何绑定抖音商店&a…...
大数据组件-Flink环境搭建
🥇🥇【大数据学习记录篇】-持续更新中~🥇🥇 个人主页:beixi 本文章收录于专栏(点击传送):【大数据学习】 💓💓持续更新中,感谢各位前辈朋友们支持…...
Java——》synchronized互斥性
推荐链接: 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…...
第十章 数组和指针
本章介绍以下内容: 关键字:static 运算符:&、*(一元) 如何创建并初始化数组 指针(在已学过的基础上)、指针和数组的关系 编写处理数组的函数 二维数组 人们通常借助计算机完成统计每月的支出…...
JVM系列 运行时数据区
系列文章目录 第一章 运行区实验 文章目录 系列文章目录前言一、堆(Heap)1.1、新生代/Young区1.1.1、Eden区1.1.2、Survival区 1.2、年老代(old区) 二、虚拟机栈(Stack)2.1、栈顶缓存技术2.2、溢出2.3、栈…...
婚纱摄影网站首页/经典网络营销案例
二、操作系统应用41.请在考生文件夹下完成如下操作:(1)在考生文件夹下建立“计算机基础练习”文件夹;(2)在“计算机基础练习”文件夹下建立“文字”﹑“图片”和“多媒体”三个子文件夹;(3)在考生文件夹下查找一个名为“1.BMP”的图片文件,将它复制到“图…...
十堰网站制作公司电话/活动策划方案详细模板
一 配置Path步骤: a:右键点击计算机 → 选择属性 → 更改设置 → 点击高级 → 点击环境变量 → 创建名为JAVA_HOME的环境变量 → 将jdk所在的目录路径(bin所在的路径)配置到JAVA_HOME变量中 b: 用;与其他变量分隔 → 在path环境变量中添…...
上海的网站开发公司/广州seo代理
往期热门文章:1、25种代码坏味道总结优化示例2、如何优雅处理重复请求/并发请求?3、使用 Redis 实现一个轻量级的搜索引擎4、线程池大小 线程数量到底设置多少?5、面试官问:数据库 delete 表数据,磁盘空间还是被一直占…...
建立网站的条件/深圳网站优化排名
...
中卫网站建设哪家好/搜索引擎营销的概念及特点
之前我遇到过这样的需求,要求在ListView中按时间对数据分栏,当时的做法是在每个ListView的item中加入时间栏的布局,然后在代码中控制时间栏 的显示与隐藏。 但其实重写Adapter两个方法后就可以完成这个任务,当ListView中带有不同布…...
长宁区公司网站建设/谷歌浏览器网页版在线
jquery如何实现excel解析,把excel中复以文本形式的复制,然后解析。Jquery无法解析Excel这个交给后端完成就好了jquery调用excel回归分析服务端代码:复制代码代码如下:ServletOutputStream out null;try{//设置csv信息response.setContentType("text/csv");String di…...