近期要爬取一个网站的数据,嗯?需要登陆才能爬取,那怎么办呢?突然灵光一闪,百度了一下发现python+selenium+PIL可以解决这个问题,为了以后需要使用的时候能给做到有资料可查,在这里就做下简单的记录吧!
这种方式有个弊端,就是可能标识的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
#退出死循环
好了,到这里登陆就写完了。