前言:这也不算心血来潮的事情,前面几天文章都涉及过,之前一直觉得很麻烦。必须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多个帖子,只用了不到一分钟。当然,还有改进的余地。
下面上图(诶,学计算机的真是注孤生,电脑便是我眼中的美女吧)