【Python3.6爬虫学习记录】(十二)PhantomJS模拟登陆并爬取教务处学生照片(哈工大)

前言:这也不算心血来潮的事情,前面几天文章都涉及过,之前一直觉得很麻烦。必须SSLVPN登陆,到教务处页面,然后进行页面跳转到照片页面。所以每次打开图片页面都要保证登陆教务处,当然可以使用cookies模拟登陆(准备到学校后再尝试这种方法),但是在这之前还要登陆SSLVPN进行跳转,所以并不可取。
当时没有技术支持,这几天都在用PhantomJS,发现了几种功能–新建标签页,页面元素截图。OK,尝试一把,没想到真成功了。
由于是截图,所以放大后,有点模糊。准备到学校后用校内网,使用cookies模拟登陆,直接下载图片。
另外,前面已经使用过模拟登陆,提到过爬取照片的原理,此处不再细说。

PhantomJS的安装
参考链接:PhantomJS 安装

代码及注释

import requests
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import time

# 通过先打开教务处,再打开照片
def DownPictureViaVPN():
    start = time.time()
    # 打开SSL VPN
    SSLVPN = 'https://vpn.hit.edu.cn/dana-na/auth/url_default/welcome.cgi'
    driver = webdriver.PhantomJS()
    driver.get(SSLVPN)
    # 输入用户密码
    user = driver.find_element_by_id('username')
    user.send_keys('学号')
    pwd = driver.find_element_by_id('password')
    pwd.send_keys('密码')
    # 选择登陆账户类型 ->下拉列表元素的定位
    driver.find_element_by_id('realm_17').find_element_by_css_selector('[value="本科生"]').click()

    # element与elements莫乱用
    login = driver.find_element_by_id('btnSubmit_6')
    login.click()

    # 成功登陆到网站;里面
    driver.find_element_by_id('browseUrl').send_keys('jwts.hit.edu.cn')
    driver.find_element_by_id('btnBrowse_3').click()

    # 教务网登陆 通用身份登陆
    time.sleep(1)
    # 以后都借助Google 开发者,直接拷贝xpath定位
    driver.find_element_by_xpath('//*[@id="dl"]').click()

    driver.find_element_by_id('username').send_keys('学号')
    driver.find_element_by_id('password').send_keys('密码')
    driver.find_element_by_xpath('//*[@id="casLoginForm"]/p[5]/button').click()

    # 打开新页面--照片
    # Grades - College - class - ranking
    # 按 年级Grade - 学院College - 班级Class - 序号Rank 循环
    for i in range(1,11):  # 10
        for j in range(1,31):  # 30
            # 格式化班级,序号
            if(i<10):
                Class = '0'+str(i)
            else:
                Class = str(i)
            if(j<10):
                Rank ='0'+ str(j)
            else:
                Rank = str(j)
            # 得到学号
            xh='学号前面通用部分'+Class+Rank
            # 尝试下载
            try:
                # 打开新标签页
                urlHead = 'https://vpn.hit.edu.cn/xswhxx/,DanaInfo=jwts.hit.edu.cn+showPhoto?xh='
                url_picture = urlHead + xh
                driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 't')
                driver.get(url_picture)
                driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 'w')

                # 照片进行操作保存
                driver.save_screenshot('StuPic\\'+xh + '.png')
                element = driver.find_element_by_xpath('/html/body/img')
                left = element.location['x']
                top = element.location['y']
                right = element.location['x'] + element.size['width']
                bottom = element.location['y'] + element.size['height']
                im = Image.open('StuPic\\'+xh + '.png')
                im = im.crop((left, top, right, bottom))
                im.save('StuPic\\'+xh + '.png')
                print('Get '+xh+' picture')
            except Exception as e:
                print(e)
    end = time.time()
    print('It takes '+str(end-start))
    driver.quit()

相关问题
①学号获取
按年级(Grade) - 学院(College) - 班级(Class) - 序号(Rank) 分别循环
可以参考学校学号的命名机制。
比如,我们学校,年级两位数,学院三位数,班级两位输,序号两位数,当然最前面还有一位,用来区分留学生,共十位数。

②新建标签页
最开始用的是这个方法,由于每张照片地址不同,要改变window.open中间的参数,就是在字符串中添加变量。但是一直出错,遂改为后面一个方法。

from selenium import webdriver

d = webdriver.PhantomJS()
d.get("https://www.baidu.com/") #先开个网页
js = " window.open('http://www.acfun.cn/')" #可以看到是打开新的标签页 不是窗口
d.execute_script(js)
d.close()

'''字符串中添加变量
    url_new = 'http://www.acfun.cn/'
    js = " window.open({url})"
    js_new = js.format(url = url_new)
    # 打开新的标签页
    driver.execute(js_new)
'''

下面这种方法,原理是直接改变本标签页的body内容,生成新标签页。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.PhantomJS()
driver.get("http://login.taobao.com")
#windows 用Keys.CONTROL 如同ctrl+t
driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 't') 
driver.get('http://mm.taobao.com/')
driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 'w') 
driver.close()

这里要区别一下,打开新窗口和打开新标签页。前者又打开一个浏览器,后者还是保持浏览器的状态,就是说,前者还要重新登录,后者保持登录状态。
参考链接:
selenium python怎么新开标签页?
python selenium打开新窗口,多窗口切换

③页面指定元素截图
简单截图 driver.save_screenshot(xh+'.png'),注意默认png格式,别的也可以,但会warning。
指定元素截图

    # 先把页面截图
    driver.save_screenshot(xh+'.png')
    # 确定元素位置
    element = driver.find_element_by_xpath('/html/body/img')
    # 得到元素详细信息--位置及大小
    left = element.location['x']
    top = element.location['y']
    right = element.location['x'] + element.size['width']
    bottom = element.location['y'] + element.size['height']
    # 根据元素信息截取图片,并重新保存
    im = Image.open(xh+'.png')
    im = im.crop((left, top, right, bottom))
    im.save(xh+'.png')
    # 注意,虽然截了两次图,但是最终只保存了第二个。

参考链接:利用 Python + Selenium 实现对页面的指定元素截图(可截长图元素)

The End
关于PhantomJS的使用,和ChromeDriver差不多,但是也有其独特的用法。
参考链接:
phantomjs使用说明
(强烈推荐看下面这篇,满满的干货)
盘点selenium phantomJS使用的坑

然后呢就是,这次是获得了我们学院的照片,300多张用了2分钟的样子。然而全年级,全校,几万人呐,岂不是得爬死。
好吧,昨晚再看多线程,基本了解了,提取了一个模板,后面会细说。做了一个实验,爬取了双一流吧700多个帖子,只用了不到一分钟。当然,还有改进的余地。

下面上图(诶,学计算机的真是注孤生,电脑便是我眼中的美女吧)
这里写图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值