十二周内容笔记
day34
01-芝麻代理作业
主要是练习了一下显式等待,写起来还是比较麻烦,但是还挺好用
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
s = Service(executable_path='../day32/chromedriver.exe')
browser = webdriver.Chrome(service=s)
URL = 'https://jahttp.zhimaruanjian.com/'
browser.get(url=URL)
# 作业内容:显式等待芝麻代理网站用户名是否出现
flag = EC.text_to_be_present_in_element((By.XPATH, '/html/body/section/aside/div[1]/a'),'zmhttp994457'
)
WebDriverWait(browser, timeout=60).until(flag)
print('登陆成功')
02-webdriver-manager模块的使用
一、webdriver-manager介绍
1.谷歌浏览器版本需要和selenium所需驱动版本一一对应,webdriver-manager可以自动检测浏览器的版本自动下载驱动。
2.webdriver-manager运行只需几行代码,并且官方文档给了,可以直接复制。
二、安装
pip install webdriver-manager
查看已安装三方模块细节:pip show webdriver-manager
三、使用
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
# 从webdriver-manager的chrome包中导入ChromeDriverManager方法
from webdriver_manager.chrome import ChromeDriverManager
# ChromeDriverManager().install():自动检测电脑上的Chrome浏览器的版本,下载对应驱动
driver_path = './'
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager(path=driver_path).install()))
03-iframe标签切换
如果你需要使用selenium自动化在输入框中输入内容及自动化点击按钮,尤其是涉及到selenium登陆账号时,一定要特别小心iframe标签。
不过也比较简单,知道有的时候切换过去就行。 以下是qq音乐登录的例子
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
# 从webdriver-manager的chrome包中导入ChromeDriverManager方法
from webdriver_manager.chrome import ChromeDriverManager
# ChromeDriverManager().install():自动检测电脑上的Chrome浏览器的版本,下载对应驱动
driver_path = './'
browser = webdriver.Chrome(service=ChromeService(ChromeDriverManager(path=driver_path).install()))
browser.implicitly_wait(10)
URL = 'https://y.qq.com/'
browser.get(url=URL)
# 点击QQ音乐右上角登录按钮
browser.find_element(By.XPATH, '//*[@id="app"]/div/div[1]/div/div[2]/span/a').click()
# 先进行iframe标签切换:iframe标签从外向内一层一层切换
iframe_1 = browser.find_element(By.XPATH, '//*[@id="login_frame"]')
browser.switch_to.frame(iframe_1)iframe_2 = browser.find_element(By.XPATH, '//*[@id="ptlogin_iframe"]')
browser.switch_to.frame(iframe_2)# 此时,browser就从最外层页面到了最内层iframe,如果还想再切回去
# browser.switch_to.default_content():可以一步到位直接切到最外层# 再从弹出来的弹窗中点击”密码登录“
browser.find_element(By.XPATH, '//*[@id="switcher_plogin"]').click()# 输入账号密码、点击登录
input_field_username = browser.find_element(By.XPATH, '//*[@id="u"]')
input_field_username.send_keys('你的账号')
input_field_password = browser.find_element(By.XPATH, '//*[@id="p"]')
input_field_password.send_keys('你的密码')
browser.find_element(By.XPATH, '//*[@id="login_button"]').click()
04-淘宝页面爬取之输入账号密码
淘宝不登陆不让搜索东西,想要有动作必须先登录。此处只是简单的输入账号密码,还没有涉及到点击登陆后检测到selenium的滑块验证码无法通过。这里用了getpass模块,不显示输入内容,老师在讲课的时候为了不暴露淘宝密码才用的,比较麻烦的是要在终端中运行,不能直接右键运行。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
# 从webdriver-manager的chrome包中导入ChromeDriverManager方法
from webdriver_manager.chrome import ChromeDriverManager# ChromeDriverManager().install():自动检测电脑上的Chrome浏览器的版本,下载对应驱动
driver_path = './'
# 引入配置项
s = ChromeService(ChromeDriverManager(path=driver_path).install())
Options = webdriver.ChromeOptions()
# 引入不关闭浏览器的相关配置项
Options.add_experimental_option("detach", True)
# 避免终端下执行代码报警告
Options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])browser = webdriver.Chrome(service=s, options=Options)
URL = 'https://www.taobao.com/'
browser.get(url=URL)
# 淘宝必须登录,否则没办法使用
# 点击淘宝页面上方的”亲,请登录“
browser.find_element(By.XPATH, '//*[@id="J_SiteNavLogin"]/div[1]/div[1]/a[1]').click()
# 寻找账号密码输入框,点击登录按钮
user_name = input('请输入账号:')
browser.find_element(By.XPATH, '//*[@id="fm-login-id"]').send_keys(user_name)
import getpass
# getpass模块中的getpass方法,能够不显示输入的内容
# 如果程序用了getpass方法,不能直接右键执行,必须在终端中使用命令执行:python ./day34/04-淘宝页面爬取(一).py
password = getpass.getpass('请输入密码:')
browser.find_element(By.XPATH, '//*[@id="fm-login-password"]').send_keys(password)
day35
01-淘宝页面爬取之滑块破解
检测到selenium后,登录出现的滑块验证码无法验证通过,这时候就需要防止selenium被监测到。主要是在点击请登陆后进行一个selenium的反检测。
# 点击淘宝页面上方的”亲,请登录“
browser.find_element(By.XPATH, '//*[@id="J_SiteNavLogin"]/div[1]/div[1]/a[1]').click()
# 寻找账号密码输入框,点击登录按钮# 跳转到登陆页面之后再尝试修改selenium的一些特性
# 防止selenium被监测,先修改js(改掉selenium的一些特性),再加载js(再去加载网页的js)
browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",{"source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"}
)
# 使用刷新重新加载页面:refresh()
browser.refresh()user_name = input('请输入账号:')
browser.find_element(By.XPATH, '//*[@id="fm-login-id"]').send_keys(user_name)
import getpass
# getpass模块中的getpass方法,能够不显示输入的内容
# 如果程序用了getpass方法,不能直接右键执行,必须在终端中使用命令执行:python ./day35/01-淘宝页面爬取之滑块破解.py
password = getpass.getpass('请输入密码:')
browser.find_element(By.XPATH, '//*[@id="fm-login-password"]').send_keys(password)
我说实话有点拉胯,或者说淘宝反爬做得挺牛,反正我弄了以后滑块还是验证失败,不过这个问题也不大,有更先进简洁的方法。
02-淘宝爬虫之cookie获取
获取cookie进行登录是相对于selenium进行账号密码登录,更好的爬取淘宝的选择。
cookie:网页在被我们访问时,会产生一个叫做cookie的东西,如果你在网页中登陆了账号,cookie中就会保存有你的账号密码的加密形式的信息。通过未过期的cookie,便可以随意登录此网站。
cookie具有时效性(生命周期):几分钟、几个小时、几天不等。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
# 从webdriver-manager的chrome包中导入ChromeDriverManager方法
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC# ChromeDriverManager().install():自动检测电脑上的Chrome浏览器的版本,下载对应驱动
driver_path = './'
# 引入配置项
s = ChromeService(ChromeDriverManager(path=driver_path).install())
Options = webdriver.ChromeOptions()
# 引入不关闭浏览器的相关配置项
Options.add_experimental_option("detach", True)
# 避免终端下执行代码报警告
Options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])browser = webdriver.Chrome(service=s, options=Options)
# 网页对selenium做检测,检测代码存在于王爷的JavaScript代码中URL = 'https://www.taobao.com/'
browser.get(url=URL)
# 淘宝必须登录,否则没办法使用
# 点击淘宝页面上方的”亲,请登录“
browser.find_element(By.XPATH, '//*[@id="J_SiteNavLogin"]/div[1]/div[1]/a[1]').click()
# 在登录页面点击二维码进行扫码登陆
browser.find_element(By.XPATH, '//*[@id="login"]/div[1]/i').click()
# 需要用户手动扫码登录# 在等待登录成功的过程,最大化的节约时间,使用显式等待,等待用户登陆成功(网页中出现了用户名)
flag = EC.text_to_be_present_in_element((By.XPATH, '//*[@id="J_SiteNavLogin"]/div[1]/div/a'),'tb612264626')
WebDriverWait(browser, 90).until(flag)
print('登陆成功')
# 获取cookie,将cookie写入txt文本文件
# get_cookies():selenium获取cookie
# cookie的形式是json数据,只不过get_cookies()已经帮我们转为了字典
my_cookie = browser.get_cookies()
with open('./cookies.txt', 'w') as file:file.write(str(my_cookie))print('cookie写入成功')
browser.quit()
03-淘宝爬虫之使用cookie进行登录
结合上面的操作获取到的cookie文本文件进行登录
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
# 从webdriver-manager的chrome包中导入ChromeDriverManager方法
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC# ChromeDriverManager().install():自动检测电脑上的Chrome浏览器的版本,下载对应驱动
driver_path = './'
# 引入配置项
s = ChromeService(ChromeDriverManager(path=driver_path).install())
Options = webdriver.ChromeOptions()
# 引入不关闭浏览器的相关配置项
Options.add_experimental_option("detach", True)
# 避免终端下执行代码报警告
Options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])browser = webdriver.Chrome(service=s, options=Options)
# 网页对selenium做检测,检测代码存在于网页的JavaScript代码中URL = 'https://www.taobao.com/'
browser.get(url=URL)# 先使用selenium访问淘宝,然后将才获取到的cookie进行注入,即可实现登陆操作。
with open('./cookies.txt', 'r') as file:# 读取cookie并转换为python的字典result = eval(file.read())for i in result:# 将每一个cookie字典注入到网页中# cookie中可能会涉及到一个secure安全性字段,一般情况下此字段不会产生影响# 正常情况下可以这么写:if i['secure'] == True:browser.add_cookie(i)browser.refresh()
# 淘宝登陆成功
04-验证码破解
常见验证码形式:
1.图片 + 数字 + 字母
2.滑块验证(淘宝的纯滑块、京东的滑块 + 拼图)
3.图片 + 数学题
4.九宫格:选择消防栓、红绿灯、公共汽车、小轿车、斑马线等
5.旋转图片,转正
6.依次点击文字
7.看草图点击九宫格图
8.游戏战斗场景
9.轨迹验证
05-图片文字验证码破解
图片中有文字,需要使用到OCR光学文字识别。python也有OCR光学文字识别的模块,可以进行文字识别,即EasyOCR模块,准确率90%+,国内有百度飞浆,准确率比EasyOCR高一些。
EasyOCR的安装:体积不小的,用一手清华镜像源下载。
pip install easyocr -i https://pypi.tuna.tsinghua.edu.cn/simple
day36
01-easyocr的使用
一、OCR简介
OCR光学文字识别,是指电子设备检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后将字符识别成计算机文字的过程。
二、easyocr识别
import easyocr
# 创建easyocr的读方法对象
read_photo = easyocr.Reader(# 1.'ch_esim':简体中文lang_list=['ch_sim', 'en'],# 2.不使用gpu,如果要使用gpu,需要下载对应gpu架构的一些文件,英伟达的gpu需要下载CUDNN、CUDAgpu=False,# 3.download_enabled=False:禁止下载模型文件,模型文件存放在国外服务器,90%的人会下载失败download_enabled=False,# 4.禁止下载的模型文件提前下载好,放到指定路径model_storage_directory='./model'
)
# 识别图片
# image参数应该传递图片数据,图片路径或图片的numpy数组或图片的二进制数据均可。
result = read_photo.readtext(image='./img.png')
print(result)
02-网页验证码破解(一)
使用easyocr对阿里云邮箱简单的数字和字母图片验证码识别。
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
# 从webdriver-manager的chrome包中导入ChromeDriverManager方法
from webdriver_manager.chrome import ChromeDriverManager# ChromeDriverManager().install():自动检测电脑上的Chrome浏览器的版本,下载对应驱动
driver_path = './'
# 引入配置项
s = ChromeService(ChromeDriverManager(path=driver_path).install())
Options = webdriver.ChromeOptions()
# 引入不关闭浏览器的相关配置项
Options.add_experimental_option("detach", True)
# 避免终端下执行代码报警告
Options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])browser = webdriver.Chrome(service=s, options=Options)
# 网页对selenium做检测,检测代码存在于网页的JavaScript代码中URL = 'http://mail.1000phone.com/alimail/auth/login?custom_login_flag=1&reurl=%2Falimail%2F'
browser.get(url=URL)# 请求完阿里邮箱,找账号输入框随便输入内容,然后点击密码输入框,等待验证码出现
iframe_1 = browser.find_element(By.XPATH, '//*[@id="page"]/div[2]/div/div/iframe')
browser.switch_to.frame(iframe_1)
iframe_2 = browser.find_element(By.XPATH, '//*[@id="ding-login-iframe"]')
browser.switch_to.frame(iframe_2)
browser.find_element(By.XPATH, '//*[@id="username"]').send_keys('1231231231')
browser.find_element(By.XPATH, '//*[@id="password"]').click()# 使用selenium针对页面验证码截图
# 休眠3秒钟等待验证码出现
time.sleep(3)
# screenshot():selenium的截图操作,可以根据指定的元素进行截图
img_path = './cap.png'
browser.find_element(By.XPATH, '//*[@id="login_checkcode_ico"]').screenshot(img_path)
import easyocr
read_photo = easyocr.Reader(lang_list=['ch_sim', 'en'],gpu=False,download_enabled=False,model_storage_directory='./model'
)
result = read_photo.readtext(image=img_path)[0][-2]
print(f'识别到的验证码结果为{result}')
虽然说easyocr识别率达到了90%多,但是毕竟是白嫖的打不过充钱的,超级鹰让你感受到充钱的快乐。
03-网页验证码破解(二)
下面就是调用超级鹰对简单验证码进行破解,超级鹰的配置文件我就不写了
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
# 从webdriver-manager的chrome包中导入ChromeDriverManager方法
from webdriver_manager.chrome import ChromeDriverManager# ChromeDriverManager().install():自动检测电脑上的Chrome浏览器的版本,下载对应驱动
driver_path = './'
# 引入配置项
s = ChromeService(ChromeDriverManager(path=driver_path).install())
Options = webdriver.ChromeOptions()
# 引入不关闭浏览器的相关配置项
Options.add_experimental_option("detach", True)
# 避免终端下执行代码报警告
Options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])browser = webdriver.Chrome(service=s, options=Options)
# 网页对selenium做检测,检测代码存在于网页的JavaScript代码中URL = 'http://mail.1000phone.com/alimail/auth/login?custom_login_flag=1&reurl=%2Falimail%2F'
browser.get(url=URL)# 请求完阿里邮箱,找账号输入框随便输入内容,然后点击密码输入框,等待验证码出现
iframe_1 = browser.find_element(By.XPATH, '//*[@id="page"]/div[2]/div/div/iframe')
browser.switch_to.frame(iframe_1)
iframe_2 = browser.find_element(By.XPATH, '//*[@id="ding-login-iframe"]')
browser.switch_to.frame(iframe_2)
browser.find_element(By.XPATH, '//*[@id="username"]').send_keys('1231231231')
browser.find_element(By.XPATH, '//*[@id="password"]').click()# 使用selenium针对页面验证码截图
# 休眠3秒钟等待验证码出现
time.sleep(3)
# screenshot():selenium的截图操作,可以根据指定的元素进行截图
img_path = './cap.png'
browser.find_element(By.XPATH, '//*[@id="login_checkcode_ico"]').screenshot(img_path)
# 导入超级鹰服务
from chaojiying import Chaojiying_Client
# 实例化超级鹰对象
cjy = Chaojiying_Client('超级鹰账号', '超级鹰密码', '948081')
# 给超级鹰传递图片二进制数据
img = open(img_path, 'rb').read()
result = cjy.PostPic(img, 1902)
print(f'识别到的验证码结果为:{result["pic_str"]}')
04-selenium简单的鼠标事件
ActionChains作用:能够将鼠标的操作步骤按照操作顺序记录下来,然后等待perform的调用,依次被触发。
开始对b站进行登录操作
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
# 从webdriver-manager的chrome包中导入ChromeDriverManager方法
from webdriver_manager.chrome import ChromeDriverManager# ChromeDriverManager().install():自动检测电脑上的Chrome浏览器的版本,下载对应驱动
driver_path = './'
# 引入配置项
s = ChromeService(ChromeDriverManager(path=driver_path).install())
Options = webdriver.ChromeOptions()
# 引入不关闭浏览器的相关配置项
Options.add_experimental_option("detach", True)
# 避免终端下执行代码报警告
Options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])browser = webdriver.Chrome(service=s, options=Options)
# 网页对selenium做检测,检测代码存在于网页的JavaScript代码中URL = 'https://www.bilibili.com/'
browser.get(url=URL)
# 请求了页面之后按照bilibili首页的一些提示性内容,先把鼠标移动到”立即登录“按钮,再点击
from selenium.webdriver.common.action_chains import ActionChains
# 创建ActionChains对象,捕获浏览器对象
ac = ActionChains(browser)
login_button = browser.find_element(By.XPATH, '//*[@id="i_cecream"]/div[2]/div[1]/div[1]/ul[2]/li[1]/li')
# move_to_element():将鼠标移动到某个元素中间
ac.move_to_element(login_button)
ac.click()
# 调用已经存储的步骤
ac.perform()
05-网页验证码的破解(三)
对b站登陆的依次点击文字的验证码和二次验证的破解,我玩了很多次也没碰上他的二次验证,不知道是什么原因,说他厉害又厉害,说不厉害也有点垃圾,直接点击取消二次验证就给他绕过了。
很多注释细节在代码里面
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
# 从webdriver-manager的chrome包中导入ChromeDriverManager方法
from webdriver_manager.chrome import ChromeDriverManager# ChromeDriverManager().install():自动检测电脑上的Chrome浏览器的版本,下载对应驱动
driver_path = './'
# 引入配置项
s = ChromeService(ChromeDriverManager(path=driver_path).install())
Options = webdriver.ChromeOptions()
# 引入不关闭浏览器的相关配置项
Options.add_experimental_option("detach", True)
# 避免终端下执行代码报警告
Options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])browser = webdriver.Chrome(service=s, options=Options)
# 网页对selenium做检测,检测代码存在于网页的JavaScript代码中URL = 'https://www.bilibili.com/'
browser.get(url=URL)
# 请求了页面之后按照bilibili首页的一些提示性内容,先把鼠标移动到”立即登录“按钮,再点击
from selenium.webdriver.common.action_chains import ActionChains# 创建ActionChains对象,捕获浏览器对象
ac = ActionChains(browser)
time.sleep(1)
login_button = browser.find_element(By.XPATH, '//*[@id="i_cecream"]/div[2]/div[1]/div[1]/ul[2]/li[1]')
# move_to_element():将鼠标移动到某个元素中间
ac.move_to_element(login_button)
ac.click()
# 调用已经存储的步骤
ac.perform() # 此时已经实现打开bilibili登录界面
time.sleep(1)
# 接下来寻找账号、密码输入框,点击登录按钮
user = browser.find_element(By.XPATH, '/html/body/div[3]/div/div[4]/div[2]/form/div[1]/input')
user.send_keys('账号')
pwd = browser.find_element(By.XPATH, '/html/body/div[3]/div/div[4]/div[2]/form/div[3]/input')
pwd.send_keys('密码')
time.sleep(2)
login = browser.find_element(By.XPATH, '/html/body/div[3]/div/div[4]/div[2]/div[2]/div[2]').click()
time.sleep(2)
# bilibili有可能出现”二次校验窗口“
if '<div class="dialog__mask" style="">' in browser.page_source:# 点击”二次校验“的取消按钮browser.find_element(By.XPATH, '/html/body/div[3]/div/div[4]/div[2]/div[1]/div/div[2]/div[1]').click()# 重新点登录login = browser.find_element(By.XPATH, '/html/body/div[3]/div/div[4]/div[2]/div[2]/div[2]').click()
# 寻找验证码
captcha = browser.find_element(By.XPATH, '/html/body/div[4]/div[2]/div[6]/div/div')
# 截图
bilibili_path = './bilibili_image.png'
captcha.screenshot(bilibili_path)
# 获取验证码的location和size属性
bili_location, bili_size = captcha.location, captcha.size
# bili_location:验证码距离网页远点(左上角)的距离(x, y)
# bili_size:验证码的宽(width)、高(height)
# 将截图上传给超级鹰
from chaojiying import Chaojiying_Client
# 实例化超级鹰对象
cjy = Chaojiying_Client('超级鹰账号', '超级鹰密码', '948081')
# 给超级鹰传递图片二进制数据
img = open(bilibili_path, 'rb').read()
result = cjy.PostPic(img, 9004)if result['err_no'] == 0:ac = ActionChains(browser)# 构建每个字的坐标for item in result['pic_str'].split('|'):x, y = item.split(',')# move_to_element_with_offset(元素, x, y):将鼠标从指定的元素中间按照指定的偏移量(x, y)移动# -(bili_size['width'] / 2) + x, -(bili_size['height'] / 2 + y):表示先将鼠标移动到验证码的左边和上边ac.move_to_element_with_offset(captcha, -(bili_size['width'] / 2) + int(x), -(bili_size['height'] / 2) + int(y)).click()# 不要点太快time.sleep(1)# for循环结束,一次性释放ac的顺序功能ac.perform()
最后对文字的点击鼠标移动的计算我刚开始还没想明白,纠结了一会儿还是明白了,鼠标位置刚开始是在验证码页面的中心点,分别减去验证码页面的一半就是为了让鼠标位置到达左上角,再去按照(x, y)对文字进行点击。