Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。所以我们可以应用在爬虫中去爬取一些需要登录才能批量采集的数据。
以下操作均通过代码实现,并且可以隐藏和伪装
from selenium import webdriver
import time # 用于线程暂停,太快的话并不直观
from PIL import Image # 用于截图
import yh # 我个人的库,封装了很多内容
from selenium.webdriver import ActionChains # 引入动作链
# options=yh.chrome_avoid()用于伪装,避免被服务器检测
bro = webdriver.Chrome(executable_path='chromedriver.exe')
time.sleep(2) # 线程暂停2s
bro.get('https://kyfw.12306.cn/otn/resources/login.html') # 12306登录页面
time.sleep(2)
bro.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click() # 点击使用账户密码登录
time.sleep(2)
bro.find_element_by_xpath('/html/body/div[2]/div[2]/div[1]/div[2]/div[3]/div/div[3]').click() # 刷新验证码
time.sleep(2)
bro.save_screenshot('a.png') # 对整个页面进行截图
code_img = bro.find_element_by_xpath('//*[@id="J-loginImg"]') # 获取验证码的位置信息
location = code_img.location # 获取验证码左上角点的
size = code_img.size # 获取验证码的尺寸
# 根据左上角的点的坐标和验证码的长宽计算出图片的右下角的点的坐标
# 由于我的电脑是笔记本电脑,存在缩放,所以*1.25
rangle = (
int(location['x']) * 1.25,
int(location['y']) * 1.25,
int(location['x'] + size['width']) * 1.25,
int(location['y'] + size['height']) * 1.25
)
print(rangle) # 打印坐标
i = Image.open('a.png') # 打开整个页面的截图
new_name = 'code.png' # 给验证码那个区域的图片取个名字(也是新图片的路径)
fp = i.crop(rangle) # 根据两点坐标截图
fp.save(new_name) # 保存
pic_str = yh.get_code('code.png', 9004)['pic_str'] # 通过超级鹰破解验证码
print(pic_str) # 打印验证码
xy_list = [] # 根据超级鹰的返回,将坐标解析成[[x,y],[x,y]]的形式
if '|' in pic_str: # 坐标不止一个的情况
temp = str(pic_str).split('|')
code_len = len(temp)
for i in range(code_len):
temp2 = temp[i].split(',')
x = int(temp2[0])
y = int(temp2[1])
xy_list.append([x, y])
else: # 坐标只有一个的情况
x = int(str(pic_str).split(',')[0])
y = int(str(pic_str).split(',')[1])
xy_list.append([x, y])
print(xy_list)
for i in xy_list:
x = i[0] * 0.8
y = i[1] * 0.8
ActionChains(bro).move_to_element_with_offset(code_img, x, y).click().perform() # 创建点击的动作链
time.sleep(2)
bro.find_element_by_id('J-userName').send_keys(yh.name_12306()) # 输入账户
time.sleep(2)
bro.find_element_by_id('J-password').send_keys(yh.pwd_12306()) # 输入密码
time.sleep(2)
bro.find_element_by_id('J-login').click() # 点击登录
time.sleep(2)
action = ActionChains(bro) # 创建动作链
div = bro.find_element_by_xpath('//*[@id="nc_1_n1z"]') # 找到需要长按的坐标
action.click_and_hold(div) # 长按
action.move_by_offset(320, 0).perform() # 向右拖动320个像素
如果直接使用的话,会被服务器监测到是Selenium框架完成的操作,所以要对他进行一个伪装,伪装成人为操作
from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
option.add_experimental_option('excludeSwitches',['enable-automation'])
bro = webdriver.Chrome(executable_path='./chromedriver.exe',options=option)
实际应用中,我们并不希望看到浏览器的操作,所以把他隐藏起来
from selenium import webdriver
from time import sleep
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
bro = webdriver.Chrome(executable_path='./chromedriver.exe',chrome_options=chrome_options)
bro = webdriver.Chrome(executable_path='chromedriver.exe')
在这步里面的我使用了与我的chrome版本对应的浏览器驱动,并且把他放在了具有全局变量的路径下,版本对应可以在网上直接搜索
https://blog.csdn.net/qq_50216270/article/details/114400616