非select 下拉框选定ul-li下拉选项, 元素是隐藏的需要用js修改为其属性为可见后,再做元素定位
遇到问题
html 中定位的下拉框内容是属性是隐藏的
<ul id="reasonselect" style="display: none" fwin="mods"> <li>广告/SPAM</li> <li>恶意灌水</li> <li>违规内容</li> <li>文不对题</li> <li>重复发帖</li> <li>--------</li> <li>我很赞同</li> <li>精品文章</li> <li>原创内容</li> </ul>
#它使用Selenium和JavaScript将<ul>元素的display属性从"none"更改为"block",以使其可见: from selenium import webdriver # 创建一个浏览器实例 driver = webdriver.Chrome() # 打开网页 driver.get('https://www.example.com') # 执行JavaScript脚本,将元素的display属性设置为'block',使其可见 script = "document.getElementById('reasonselect').style.display = 'block';" driver.execute_script(script)
# 定位元素 点击
# 关闭浏览器 driver.quit()
代码示例
# login_code.py # 导包 from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep from selenium.webdriver.chrome.options import Options import pytesseract # 导入ocr库 from PIL import Image # 导入图像处理库 import ddddocr # 导入下拉框 from selenium.webdriver.support.select import Select # 定义类 class GetEle: def __init__(self,driver): self.driver=driver def login_name_psw(self,loc_name,loc_psw,loc_submit,login_name,login_psw): # 账号和密码输入 driver.find_element(By.CSS_SELECTOR,loc_name).send_keys(login_name) driver.find_element(By.CSS_SELECTOR, loc_psw).send_keys(login_psw) driver.find_element(By.CSS_SELECTOR, loc_submit).click() def submit_login(self,loc): driver.find_element(By.CSS_SELECTOR, loc).click() class CodePass: def __init__(self,driver): self.driver=driver def get_code(self,loc_code): # 获取全屏截图,获取坐标位置 ,截图保存 # 第一步 ---------获取到验证码的位置,截图,获取坐标 ele_cap = driver.find_element(By.CSS_SELECTOR, loc_code) # 获取元素的位置和大小 location = ele_cap.location size = ele_cap.size print(f"获取验证码元素位置location:{location},获取验证码元素大小size:{size}") # 获取整个页面截图 driver.save_screenshot("code.png") sleep(2) # 打开照片 captcha_image = Image.open("code.png") # 获取验证码的上下左右坐标 left = int(location['x']) top = int(location['y']) right = int(location['x'] + size['width']) bottom = int(location['y'] + size['height']) print(f"坐标展示 left:{left},top:{top},right:{right},bottom:{bottom}") # 第二步------------------利用坐标信息对截图图片做裁剪 # 打开图片 image = Image.open('code.png') # 裁剪图片 cropped_image = image.crop((left, top, right, bottom)) # 显示裁剪后的图片 # cropped_image.show() # 保存裁剪后的图片 cropped_image.save("code.png") # 延迟3秒 sleep(3) # 关闭照片 image.close() # 第三步-----------------------对截图做OCR识别 # 实例化一个ocr ocr = ddddocr.DdddOcr() # 以二进制格式打开verf.png图片用于只读 with open('code.png', 'rb') as f: # 用来读取文件 img_bytes = f.read() # 识别图片中的内容 res = ocr.classification(img_bytes) # 输出内容 print('识别出的验证码为:' + res) return res def input_code(self,loc,res): # 找到元素,输入code,点击 登录 driver.find_element(By.CSS_SELECTOR,loc).send_keys(res) class TieDel: def __init__(self,driver): self.driver=driver ''' # 1 默认板块的位置 moren_loc='[href*="forum.php?mod=forumdisplay"]>img' # 2 点击默认板块的位置,进入详情列表 t.click_del() # 3 列表的第一个帖子 one_tie_loc='#content_1+[href*="forum.php?mod=viewthread"]' # 4 第8个管理的位置 loc_8='#manage8' ''' # 1 点击默认板块的位置 def c_moren(self, loc_moren): driver.find_element(By.CSS_SELECTOR,loc_moren).click() # 2 在贴吧详情列表,点击第一个帖子 def c_tie_1(self, loc_tie_1): driver.find_element(By.CSS_SELECTOR,loc_tie_1).click() # 3 点击第一个帖子列表中的第8个回复里管理的位置 def c_replay_num(self, loc_replay_num): driver.find_element(By.XPATH,loc_replay_num).click()# XPATH # 4 点击弹出删除按钮 def c_del(self, loc_del): driver.find_element(By.CSS_SELECTOR, loc_del).click() # 5 写删除的原因 def input_reason(self, loc_reason,reason): driver.find_element(By.CSS_SELECTOR, loc_reason).send_keys(reason) # 5 选择删除的原因 def select_reason(self, loc_reason,reason_text): # 第一步 修改属性为可见 # 执行JavaScript脚本,将元素的display属性设置为'block',使其可见 script = "document.getElementById('reasonselect').style.display = 'block';" driver.execute_script(script) sleep(3) # 第二步点击下拉框 点击弹出的某个选项 # css [onclick*="showselect"] driver.find_element(By.CSS_SELECTOR, loc_reason).click() print("已点击下拉框") sleep(5) # xpath //li[text()='恶意灌水'] driver.find_element(By.XPATH, reason_text).click() # 6 点击确认删除 def del_submit(self, loc_del_submit): driver.find_element(By.CSS_SELECTOR, loc_del_submit).click() # 调用 if __name__ == '__main__': ''' # 创建无头浏览器选项 options = Options() options.add_argument("--headless") # 调用driver driver=webdriver.Chrome(options=options) ''' driver = webdriver.Chrome() # 最大化窗口 driver.maximize_window() # url url=r"http://XXX/forum.php" driver.get(url) # 实例化类 web_e=GetEle(driver) # 调用登录 loc_name='#ls_username' loc_psw='#ls_password' loc_submit='.pn.vm>em' login_name='admin' login_psw='123456' web_e.login_name_psw(loc_name,loc_psw,loc_submit,login_name,login_psw) # 输入验证码 sleep(3) print("进入第二阶段 输入验证码") c=CodePass(driver) code_loc = 'img[onclick*="updateseccode"]' res=c.get_code(code_loc) # 调用获取验证码 input_code_loc = 'input[id*=seccodeverify]' c.input_code(input_code_loc,res) # 提交登录按钮 submit_loc = '[name=loginsubmit]' web_e.submit_login(submit_loc) # 重头戏 进入删除帖子模块 t = TieDel(driver) print("进入删除帖子模块") # 1 默认板块的位置 loc_moren='[href*="forum.php?mod=forumdisplay"]>img' t.c_moren(loc_moren) print("1.点击默认板块的位置") # 2 列表的第一个帖子的位置 loc_tie_1='#content_1+[href*="forum.php?mod=viewthread"]' t.c_tie_1(loc_tie_1) print("2.点击第一个帖子的位置") # 3 第一个帖子列表中的第8个回复里【管理】按钮的位置 sleep(2) loc_replay_num='//*[starts-with(@id, "manage") and number(substring-after(@id, "manage")) > 11]' t.c_replay_num(loc_replay_num) print("3.点击第一个帖子列表中的第8个回复里管理的位置") # 4 弹出删除按钮 sleep(2) loc_del='[onclick="modaction(\'delpost\')"]' t.c_del(loc_del) print("4.点击管理的按钮") ''' 5 输入删除的理由 sleep(2) loc_reason='#reason' t.input_reason(loc_reason,'恶意灌水') print("5.输入删除的理由") ''' # 5 选择删除的理由 sleep(2) print("----开始选择删除理由") loc_reason='[onclick*="showselect"]' reason_text='//*[@id="reasonselect"]/li[2]' t.select_reason(loc_reason,reason_text) print("5.完成选择删除的理由,恶意灌水") # 6 点击确定删除按钮 sleep(2) loc_del_submit='#modsubmit' t.del_submit(loc_del_submit) print("6.点击删除的确认按钮") # 退出 sleep(3) driver.quit()