前提:
1.Python是3.9版本
2.anaconda 3安装好后比较方便
3.import的库必须都pip install过
4.本文仅供自己学习使用,请勿随意爬取他人网站,造成的不良后果,本人概不负责
5.秉承开源精神,但转载请注明出处
6.谷歌驱动器下载地址:http://chromedriver.storage.googleapis.com/index.html(或者https://googlechromelabs.github.io/chrome-for-testing/)(安装了他,程序才能调起谷歌浏览器),要把谷歌驱动器也加入到环境变量(把解压后的chromedriver文件放到/usr/local/bin/下)。
7.程序的作用:自动读取XLS中的账密,写到目标网页的对应位置,自动识别验证码数字和字母,自动输入识别到的验证码,登录成功后自动获取想要的数据。部分代码需要根据自身情况修改。
代码如下,根据自己运行环境情况调整代码内部分参数
from PIL import Image
# 确保已安装必要的第三方库
import requests
# 操作操作系统
import os
# ddddocr是验证码识别OCR工具
import ddddocr
from selenium import webdriver
from selenium.webdriver.support.ui import Select
# 注意:如果你的selenium 版本是4以上,请给下面一行的注释取消,并且下方的语法也要从find_element_by_xpath变为find_element(By.XPATH, "//*[@id='password']")
#from selenium.webdriver.common.by import By
# 导入操作xls的插件
import xlrd, xlwt, xlutils.copy
# from xlutils.copy import copy
import time
from datetime import datetime
# 打开xls
data = xlrd.open_workbook(r"/Users/Desktop/foo.xls")
# copy_data = copy(data)
# 写Excel
table = data.sheets()[1] # 打开第一张表
# 获取全部的行数
nrows = table.nrows
workbook = xlwt.Workbook(encoding='utf-8')
sheet1 = workbook.add_sheet(u"new", cell_overwrite_ok = True)
# xlwt_sheet = copy_data.get_sheet(1) #获取sheet对象
# 循环逐行打印
for i in range(nrows):
# 获取账号:
if i == 0:
continue
# 账号是xls中记录的账号
username = str(table.cell_value(i,1))
password = username[-5:]
# 指定浏览器为chrome,需先把selenium的chromeDriver放在python安装目录
driver=webdriver.Chrome()
# 输入自己想访问的网站http://xxx.html
driver.get(r'http://xxxx/index.html')
time.sleep(0.3)
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66'
}
# 窗口最大化,加载完毕会耗费几秒钟,请耐心等待
driver.maximize_window()
time.sleep(0.3)
# 输入账号 j_username为input的name值
driver.find_element_by_xpath('//*[@name="username"]').send_keys(username)
# 注意:如果你的selenium 版本是4以上,请给下面一行的注释取消,并注释上一行代码
#driver.find_element(By.XPATH, "//*[@id='user']").send_keys('aaaaa')
# 输入密码
driver.find_element_by_xpath('//*[@name="password"]').send_keys(password)
# 注意:如果你的selenium 版本是4以上,请给下面一行的注释取消,并注释上一行代码
#driver.find_element(By.XPATH, "//*[@id='password']").send_keys('bbbbbbbb')
# 点选验证码输入框,生成验证码图片
driver.find_element_by_xpath('//*[@name="veryCode"]').click()
# 注意:如果你的selenium 版本是4以上,请给下面一行的注释取消,并注释上一行代码
#driver.find_element(By.XPATH, "//*[@id='password']").send_keys('bbbbbbbb')
time.sleep(0.5)
#******************** 老的图片验证码识别方法Start**************************
# 截取当前网页变成图片,并存储到固定位置
driver.save_screenshot('/Users/Desktop/xxx/1.png')
#获取验证码的对象
yzm_btn = driver.find_element_by_id('imgObj')
# 通过验证码对象获取坐标
loc = yzm_btn.location
size = yzm_btn.size
# 计算缩放比例
left = loc['x']*2 # 计算左边界
top = loc['y']*2 # 计算上边界
right = (loc['x'] + size['width'])*2 # 计算右边界
bottom = (loc['y'] + size['height'])*2 # 计算下边界
# 将上下左右边界值放到元组中(注意顺序:左 上 右 下)
local = (left, top, right, bottom)
# 使用PIL模块对页面图片进行再次截图(获取验证码图片),将验证码图片保存
pic = Image.open('/Users/Desktop/xxx/1.png')
newimg = pic.crop(local)
newimg.save('/Users/Desktop/xxx/zym.png')
with open('/Users/Desktop/xxx/zym.png', 'rb') as f:
img_bytes = f.read()
ocr = ddddocr.DdddOcr()
ocrCode = ocr.classification(img_bytes)
# 写入识别的验证码值
driver.find_element_by_xpath('//*[@name="veryCode"]').send_keys(ocrCode.upper())
#******************** 老的图片验证码识别方法End**************************
#******************** 新的图片验证码识别方法Start,两种识别方法二选一,推荐使用新的更准确**************************
#获取验证码的对象
yzm_btn = driver.find_element(By.XPATH, "//*[@id='yzbImg']")
# 定位到验证码元素,因为验证码是以base64格式保存,所有需要先提取出验证码,保存成.png格式图片
el = driver.find_element(By.XPATH, '//div[@class="form_yzm"]/img')
# 将当前元素的屏幕截图保存为PNG图像文件
el.screenshot('F:\\zym.png')
# 识别验证码
ocr = ddddocr.DdddOcr()
with open("F:\\zym.png", "rb") as f:
image = f.read()
res = ocr.classification(image)
# 写入识别的验证码值
driver.find_element(By.XPATH, '//*[@id="code"]').send_keys(res)
# 输入完毕,点击确认按钮。
driver.find_element(By.XPATH, '//*[@id="loginBtn"]').click()
time.sleep(0.4)
#******************** 新的图片验证码识别方法End**************************
# 输入完毕,点击确认按钮。
driver.find_element_by_class_name('NormalSubmit').click()
# 4版本通过classname获取元素的写法
#driver.find_element(By.CLASS_NAME, '//*[@id="bd_detail_btn"]').click()
time.sleep(0.5)
# 判断验证码识别的对不对
# try:
# alert_element = driver.switch_to.alert
# alert_element.accept()
# print(alert_element)
# #把异常消息赋予一个"ex"变量
# except Exception as ex:
# print(ex)
# 跳转到指定的URL
driver.get(r"http://xxx.html/二级页面")
time.sleep(1)
mobile = driver.find_element_by_xpath('//*[@name="mobile"]')
find_mobile = mobile.get_attribute("value")
sheet1.write(i, 1, username)
sheet1.write(i, 2, find_mobile)
driver.quit()
workbook.save("/Users/Desktop/zzz.xls")