python+selenium+PIL自动登陆网站

近期要爬取一个网站的数据,嗯?需要登陆才能爬取,那怎么办呢?突然灵光一闪,百度了一下发现python+selenium+PIL可以解决这个问题,为了以后需要使用的时候能给做到有资料可查,在这里就做下简单的记录吧!

一、写入cookie的形式

这种方式有个弊端,就是可能标识的cookie会变,在下次登陆中不能登陆成功。

from selenium import webdriver
#引入selenium模块
opt = webdriver.ChromeOptions()
opt.set_headless()
#设置不在前台打开chrome浏览器
driver = webdriver.Chrome('G:/py_2019\Reptile/Reptile001/chrome/chromedriver.exe',options=opt)
#使用chrome引擎,并指定chromedriver所在位置
driver.maximize_window()
#chrome浏览器窗口最大化
cookies1 = {'httpOnly': True, 'path': '/', 'secure': False, 'name': 'JSESSIONID', 'domain': 'www.xxxxx.org', 'value': 'xxxxxxxxxxxxxxxxxxxx'}
cookies2 = {'httpOnly': False, 'name': 'loginname', 'path': '/', 'secure': False, 'expiry': 1560754315, 'domain': 'www.xxxxx.org', 'value': 'xxxxxxxxxxxxxxxxxxxx'}
cookies3 = {'httpOnly': False, 'name': 'password', 'path': '/', 'secure': False, 'expiry': 1560754315, 'domain': 'www.xxxxx.org', 'value': 'xxxxxxxxxxxxxxxxxxxx'}
#将标识、登录名、密码的cookie赋值给变量。cookie的查询方法有F12查看和使用引擎手动登录获取
#driver.get_cookies()手动登录成功后获取cookie的方法
driver.get('http://www.xxxxx.org/main/index')
#先打开一次需要访问的链接,要不然可以在增加cookie的时候报错
driver.delete_all_cookies()
#清除所有cookie
driver.add_cookie(cookies1)
driver.add_cookie(cookies2)
driver.add_cookie(cookies3)
#将得到的cookie写入需要访问的网站
driver.get('http://www.xxxxx.org/main/index')
#再次访问需要访问的网站,OK,这样就能访问需要登录的网页了

二、完全模拟手动登陆的方式

from  selenium import webdriver
from PIL import Image
import  pytesseract
import time
#引入模块
opt = webdriver.ChromeOptions()
opt.set_headless()
#设置不在前台打开chrome浏览器
driver = webdriver.Chrome('G:/py_2019\Reptile/Reptile001/chrome/chromedriver.exe',options=opt)
#使用chrome引擎,并指定chromedriver所在位置
driver.maximize_window()
#chrome浏览器窗口最大化
driver.get('http://www.xxxx.org')
#打开需要登录的网站
def login(): #函数实现登录的功能
    code_location = driver.find_elements_by_id("codeImg")[0].location
    #定位验证码所在的位置,结果一般为{'x':数字,'y':数字}
    code_size = driver.find_elements_by_id("codeImg")[0].size
    #确定验证码的大小,结果一般为{'width':数字,'height':数字}
    left = code_location['x']
    #定位验证码左边的像素
    right = code_location['x'] +code_size['width']
    # 定位验证码右边的像素
    top = code_location['y']
    # 定位验证码顶部的像素
    bottom = code_location['y'] + code_size['height']
    # 定位验证码底部的像素
    driver.save_screenshot("test.png",)
    #截取打开网站页面的图片并存储为test.png,必须为png格式
    all_img = Image.open('G:/py_2019/Reptile/test.png')
    #打开刚保存的图片,可以为绝对路径,亦可为相对路径
    code_img = all_img.crop((left, top, right, bottom))
    #截取验证码所在的位置
    code_img.save('code.png')
    #将截取的验证保存为图片code.png
    img = Image.open('code.png')
    # 打开保存的验证的图片,可以为绝对路径,亦可为相对路径
    text = pytesseract.image_to_string(img,lang='chi_sim')
    #获取验证码中的文字
    driver.find_elements_by_id('loginname')[0].clear()
    #清除默认的用户名
    driver.find_elements_by_id('password')[0].clear()
    #清除默认的密码
    driver.find_elements_by_id('loginname')[0].send_keys("xxx")
    #输入登录的用户名
    driver.find_elements_by_id('password')[0].send_keys("xxx")
    #输入登录的密码
    driver.find_elements_by_id("code")[0].send_keys(text)
    #输入得到的验证码
    driver.find_elements_by_xpath('//*[@id="to-recover"]')[0].click()
    #点击登录按钮

while True:#为什么写成循环了?因为怕识别的验证码不准,所以采用循环直到登录成功为止
    login()#调用函数
    time.sleep(5)#休息五秒,为了确保登录成功并跳转到登录成功的主页
    if driver.find_elements_by_xpath('//*[@id="sidebar"]/ul/li[1]/a/span') == []:
    #选择一个只有登录成功才能显示的元素来作为登录成功与否判断,如果没找到,则证明登录失败
        print("登录失败")
        driver.find_elements_by_id("codeImg")[0].click()
        #登录失败后点击验证码刷新验证码返回执行登录函数
        
    else:
        print("登陆成功")
        break
        #退出死循环

好了,到这里登陆就写完了。

你可能感兴趣的:(爬虫,python)