使用python的requests库简单爬取,使用xpath解析内容

可以获取个人信息、个人照片、成绩单和课表

github地址:https://github.com/PythonerKK/GZCC-Spider



首先使用浏览器开发者调试工具找到登录页面的准确地址:http://jwxw.gzcc.cn/default2.aspx

然后找到验证码的地址:http://jwxw.gzcc.cn/CheckCode.aspx

将验证码保存让用户输入即可

登录时发送POST请求,需要注意要提交一个叫__VIEWSTATE的字段,并且要携带cookies

发送POST后,如果登录成功则返回用户页面,判断即可

  1. __VIEWSTATE=re.compile('name="__VIEWSTATE" value="(.*?)"').findall(data.text)[0]
  2. resource=requests.post(login_url,data=post_data,cookies=cookies,headers=headers).text
  3. if '活动报名' in resource:
  4. print('登录成功!')
  5. dom_tree=etree.HTML(resource)
  6. name=dom_tree.xpath('//span[@id="xhxm"]/text()')
  7. name=name[0]
  8. print('欢迎回来 '+name)
  9. return (cookies,name.split('同')[0])
  10. else:
  11. print('登录失败!')
  12. exit(0)

登录成功,输出:xxx同学,你好!

接下来需要获取个人信息、个人照片、成绩单

原理同上,注意携带cookies,成绩页面获取还需要携带__VIEWSTATE字段

效果如下:

全部代码:

  1. # -*- coding: utf-8 -*-
  2. """
  3. :author: KK
  4. :url: http://github.com/PythonerKK
  5. :copyright: © 2018 KK <705555262@qq.com.com>
  6. :license: MIT, see LICENSE for more details.
  7. """
  8. import requests
  9. import re
  10. from lxml import etree
  11. from urllib.request import quote
  12. import csv
  13. def login(username,password):
  14. '''
  15. 登录方正教务系统(广州商学院)
  16. :param username: 学号
  17. :param password: 密码
  18. :return: tuple(cookies,name) 返回一个元组
  19. '''
  20. headers = {
  21. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
  22. }
  23. login_url = 'http://jwxw.gzcc.cn/default2.aspx'
  24. checkcode_url = 'http://jwxw.gzcc.cn/CheckCode.aspx'
  25. data=requests.get(login_url)
  26. __VIEWSTATE=re.compile('name="__VIEWSTATE" value="(.*?)"').findall(data.text)[0]
  27. cookies=data.cookies
  28. checkcode=requests.get(checkcode_url,cookies=cookies,headers=headers)
  29. with open('checkcode.jpg','wb') as f:
  30. f.write(checkcode.content)
  31. code=input('请输入验证码:')
  32. while '-' in code:
  33. checkcode = requests.get(checkcode_url, cookies=cookies, headers=headers)
  34. with open('checkcode.jpg', 'wb') as f:
  35. f.write(checkcode.content)
  36. code = input('请重新输入验证码:')
  37. post_data={
  38. '__VIEWSTATE':__VIEWSTATE,
  39. 'txtUserName':username,
  40. 'Textbox1':'',
  41. 'TextBox2':password,
  42. 'txtSecretCode':code,
  43. 'RadioButtonList1':'%D1%A7%C9%FA',
  44. 'Button1':'',
  45. 'lbLanguage':'',
  46. 'hidPdrs':'',
  47. 'hidsc':'',
  48. }
  49. resource=requests.post(login_url,data=post_data,cookies=cookies,headers=headers).text
  50. if '活动报名' in resource:
  51. print('登录成功!')
  52. dom_tree=etree.HTML(resource)
  53. name=dom_tree.xpath('//span[@id="xhxm"]/text()')
  54. name=name[0]
  55. print('欢迎回来 '+name)
  56. return (cookies,name.split('同')[0])
  57. else:
  58. print('登录失败!')
  59. exit(0)
  60. def get_information(cookies,username,name):
  61. '''
  62. 获取个人信息,并导出照片
  63. :param cookies: cookies
  64. :param username: 学号
  65. :param name: 姓名
  66. :return: None
  67. '''
  68. #获取用户个人信息
  69. headers={
  70. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
  71. 'Referer':'http://jwxw.gzcc.cn/xs_main.aspx?xh='+username
  72. }
  73. information_url='http://jwxw.gzcc.cn/xsgrxx.aspx?xh='+username+'&xm='+name+'&gnmkdm=N121501'
  74. data=requests.get(information_url,cookies=cookies,headers=headers)
  75. dom_tree=etree.HTML(data.text)
  76. sex=dom_tree.xpath('//span[@id="lbl_xb"]/text()')[0]
  77. born=dom_tree.xpath('//span[@id="lbl_csrq"]/text()')[0]
  78. id=dom_tree.xpath('//span[@id="lbl_sfzh"]/text()')[0]
  79. race=dom_tree.xpath('//span[@id="lbl_mz"]/text()')[0]
  80. polity=dom_tree.xpath('//span[@id="lbl_zzmm"]/text()')[0]
  81. academic=dom_tree.xpath('//span[@id="lbl_xy"]/text()')[0]
  82. xi=dom_tree.xpath('//span[@id="lbl_xi"]/text()')[0]
  83. major=dom_tree.xpath('//span[@id="lbl_zymc"]/text()')[0]
  84. c=dom_tree.xpath('//span[@id="lbl_pyfx"]/text()')[0]
  85. edu=dom_tree.xpath('//span[@id="lbl_CC"]/text()')[0]
  86. phone=dom_tree.xpath('//input[@name="TELNUMBER"]/@value')[0]
  87. school=dom_tree.xpath('//input[@name="byzx"]/@value')[0]
  88. dorm=dom_tree.xpath('//input[@name="ssh"]/@value')[0]
  89. email=dom_tree.xpath('//input[@name="dzyxdz"]/@value')[0]
  90. loc_code=dom_tree.xpath('//input[@name="yzbm"]/@value')[0]
  91. #获取用户照片
  92. headers_image={
  93. 'Accept':'image/webp,image/apng,image/*,*/*;q=0.8',
  94. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
  95. 'Referer':'http://jwxw.gzcc.cn/xsgrxx.aspx?xh='+username+'&xm='+quote(name)+'&gnmkdm=N121501',
  96. }
  97. image_url=re.compile('img id="xszp" src="(.*?)"').findall(data.text)
  98. image_url='http://jwxw.gzcc.cn/'+image_url[0]
  99. image_url=image_url.replace('amp;','')
  100. image_data=requests.get(image_url,headers=headers_image,cookies=cookies)
  101. with open('photo.png', 'wb') as f:
  102. f.write(image_data.content)
  103. print('照片导出成功!')
  104. from docx import Document
  105. from docx.shared import Inches
  106. document = Document()
  107. document.styles['Normal'].font.name = u'黑体'
  108. document.add_heading(name+'的个人信息',0)
  109. pic = document.add_picture('photo.png', width=Inches(1.5))
  110. document.add_paragraph('个人资料')
  111. document.add_paragraph('姓名:'+name)
  112. document.add_paragraph('性别:' + sex)
  113. document.add_paragraph('出生:' + born)
  114. document.add_paragraph('身份证号:' + id)
  115. document.add_paragraph('种族:' + race)
  116. document.add_paragraph('政治面貌:' + polity)
  117. document.add_paragraph('系部:' + xi)
  118. document.add_paragraph('学院:' + academic)
  119. document.add_paragraph('专业:' + major)
  120. document.add_paragraph('班级:' + c)
  121. document.add_paragraph('学历:' + edu)
  122. document.add_paragraph('手机号:' + phone)
  123. document.add_paragraph('毕业高中:' + school)
  124. document.add_paragraph('宿舍号:' + dorm)
  125. document.add_paragraph('邮箱号:' + email)
  126. document.add_paragraph('邮编:' + loc_code)
  127. document.save(username+'个人信息.docx')
  128. print('个人资料导出成功!')
  129. def get_curriculum(cookies,username,name):
  130. '''
  131. 获取学生当前课表
  132. :param cookies:cookies
  133. :param username: 学号
  134. :param name: 姓名
  135. :return: None
  136. '''
  137. headers={
  138. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
  139. 'Referer':'http://jwxw.gzcc.cn/xs_main.aspx?xh='+username
  140. }
  141. curriculum_url='http://jwxw.gzcc.cn/xskbcx.aspx?xh='+username+'&xm='+password+'&gnmkdm=N121603'
  142. data=requests.get(curriculum_url,cookies=cookies,headers=headers)
  143. # import lxml
  144. # dom_tree=etree.HTML(data.text)
  145. # curriculum=dom_tree.xpath('//table[@id="Table1"]')
  146. print(data.text)
  147. def get_score(cookies,username,name):
  148. '''
  149. 获取所有考试成绩,并导出csv
  150. :param cookies: cookies
  151. :param username: 学号
  152. :param name: 姓名
  153. :return: Boolean
  154. '''
  155. headers={
  156. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
  157. 'Referer':'http://jwxw.gzcc.cn/xs_main.aspx?xh='+username
  158. }
  159. first_url='http://jwxw.gzcc.cn/xscjcx.aspx?xh='+username+'&xm='+name+'&gnmkdm=N121605'
  160. data=requests.get(first_url,cookies=cookies,headers=headers)
  161. viewstate=re.compile('name="__VIEWSTATE" value="(.*?)"').findall(data.text)
  162. viewstate=viewstate[0]
  163. headers={
  164. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
  165. 'Referer':'http://jwxw.gzcc.cn/xscjcx.aspx?xh='+username+'&xm='+quote(name)+'&gnmkdm=N121605'
  166. }
  167. print(headers)
  168. score_url='http://jwxw.gzcc.cn/xscjcx.aspx?xh='+username+'&xm='+name+'&gnmkdm=N121605'
  169. post_data={
  170. '__EVENTTARGET':'',
  171. '__EVENTARGUMENT':'',
  172. '__VIEWSTATE':viewstate,
  173. 'hidLanguage':'',
  174. 'ddlXN':'',
  175. 'ddlXQ':'',
  176. 'ddl_kcxz':'',
  177. 'btn_zcj':'%C0%FA%C4%EA%B3%C9%BC%A8'
  178. }
  179. scores=requests.post(score_url,cookies=cookies,headers=headers,data=post_data)
  180. all=re.compile('<td>(.*?)</td><td>(\d+)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td></td><td></td>').findall(scores.text)
  181. for i in all:
  182. with open('score.csv', 'a', newline='') as f:
  183. try:
  184. csv_out=csv.writer(f,dialect='excel')
  185. csv_out.writerow([i[0],i[1],i[2],i[3],i[4],i[5].replace('&nbsp;',''),i[6],i[7],i[8],i[9].replace('&nbsp;',''),i[10].replace('&nbsp;',''),i[11].replace('&nbsp;',''),i[12].replace('&nbsp;','')])
  186. except Exception:
  187. print('导出失败!')
  188. return False
  189. print('成绩导出成功!')
  190. return True
  191. def change_password(cookies,username,password,password1,password2):
  192. '''
  193. 修改密码
  194. :param cookies: cookies
  195. :param username: 学号
  196. :param password: 原密码
  197. :param password1: 新密码
  198. :param password2: 再次输入新密码
  199. :return: None
  200. '''
  201. url='http://jwxw.gzcc.cn/mmxg.aspx?xh='+username+'&gnmkdm=N121502'
  202. headers={
  203. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
  204. 'Referer':'http://jwxw.gzcc.cn/xs_main.aspx?xh='+username
  205. }
  206. data=requests.get(url,headers=headers,cookies=cookies)
  207. viewstate=re.compile('name="__VIEWSTATE" value="(.*?)"').findall(data.text)
  208. viewstate=viewstate[0]
  209. postdata={
  210. 'Button1':'%D0%DE++%B8%C4',
  211. '__VIEWSTATE':viewstate,
  212. 'TextBox2':password,
  213. 'TextBox3':password1,
  214. 'Textbox4':password2,
  215. }
  216. data=requests.post(url,data=postdata,cookies=cookies,headers=headers)
  217. print('密码修改成功!')
  218. if __name__ == '__main__':
  219. print('广州商学院正方教务系统登录')
  220. username=input('请输入学号:')
  221. password=input('请输入密码:')
  222. cookies,name=login(username,password)
  223. #get_information(cookies,username,name)
  224. #get_curriculum(cookies,username,name)
  225. #get_score(cookies,username,name)
  226. #change_password(cookies,username,password,password1=password,password2=password)

广州商学院Python正方教务系统爬虫(获取个人信息成绩课表修改密码)的更多相关文章

  1. HttpClient+Jsoup模拟登陆贺州学院教务系统,获取学生个人信息

    前言 注:可能学校的教务系统已经做了升级,当前的程序不知道还能不能成功获取信息,加上已经毕业,我的账户已经被注销,试不了,在这里做下思路跟过程的记录. 在我的毕业设计中”基于SSM框架贺州学院校园二手 ...

  2. JavaScript之正方教务系统自动化教评[插件-转载]

    [声明]本插件系学院学长原创,非博主所创,发布此处,仅供学习和效仿. /** * @name:正方教务系统自动化教评-插件 * * @author:chenzhongshu * @date:2017- ...

  3. 以正方教务系统为例,用php模拟登陆抓取课表、空教室

    课程格子和超级课程表这两个应用,想必大学生都很熟悉,使用自己的学号和教务系统的密码,就可以将自己的课表导入,随时随地都可以在手机上查看. 其实稍微了解一点php的话,我们也可以做一个类似这样的web ...

  4. 大学生可用来接单,利用Python实现教务系统扩容抢课!

    最近一学期一次的抢课大戏又来了,几家欢乐几家愁.O(∩_∩)O哈哈~(l我每次一选就过了hah,我还是有欧的时候滴).看着他们盯着教务系统就着急,何况我们那教务系统,不想说什么.emmm 想周围的朋友 ...

  5. 课程助理For Windows(预览版,正方教务系统学生查分工具)

    其实盖子已经开发了一个功能更强大的版本,但是那个版本依然基于正方系统,也就是说只要正方系统跪了或者张院士在网站上做点手脚,这个小工具就会失效. 今天给大家的版本虽然功能及其简单.界面极端丑陋,但是通过 ...

  6. python requests模拟登陆正方教务管理系统,并爬取成绩

    最近模拟带账号登陆,查看了一些他人的博客,发现正方教务已经更新了,所以只能自己探索了. 登陆: 通过抓包,发现需要提交的值 需要值lt,这是个啥,其实他在访问登陆页面时就产生了 session=req ...

  7. Python实现简单的爬虫获取某刀网的更新数据

    昨天晚上无聊时,想着练习一下Python所以写了一个小爬虫获取小刀娱乐网里的更新数据 #!/usr/bin/python # coding: utf-8 import urllib.request i ...

  8. HttpURLConnection模拟登录学校的正方教务系统

    教务系统登录界面 如图1-1 1-1 F12-->network查看登录教务系统需要参数: __VIEWSTAT txtUserName TextBox2 txtSecretCode Radio ...

  9. 手把手教你使用Python网络爬虫获取招聘信息

    1.前言 现在在疫情阶段,想找一份不错的工作变得更为困难,很多人会选择去网上看招聘信息.可是招聘信息有一些是错综复杂的.而且不能把全部的信息全部罗列出来,以外卖的58招聘网站来看,资料整理的不清晰. ...

随机推荐

  1. Cuckoo for Hashing(hash)hunnuoj

    Problem B:Cuckoo for HashingAn integer hash table is a data structure that supports insert, delete a ...

  2. A计划 hdu2102(bfs一般题)

    A计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  3. 使用Druid网上监控

    0.添加依赖 <!--druid连接池--> <dependency> <groupId>com.alibaba</groupId> <artif ...

  4. 解决:oracle+myBatis ResultMap 类型为 map 时,表字段类型有 Long/Blob/Clob 时报错

    前言:最近在做一个通用查询单表的组件,所以 sql 的写法就是 select *,然后 resultType="map" .如果数据库中的表里有字段类型为 Long 等类型时,my ...

  5. 开源框架--NFine.Framework学习(01)

    框架底层采用经典DDD架构,UI层采用jQuery+Bootstrap打造而成的一套符合中国式操作习惯的快速开发框架. 前后端使用技术 1.前端技术 JS框架:jquery-2.1.1.Bootstr ...

  6. cf250D. The Child and Sequence(线段树 均摊复杂度)

    题意 题目链接 单点修改,区间mod,区间和 Sol 如果x > mod ,那么 x % mod < x / 2 证明: 即得易见平凡, 仿照上例显然, 留作习题答案略, 读者自证不难. ...

  7. KCF跟踪算法 入门详解

    一.算法介绍 KCF全称为Kernel Correlation Filter 核相关滤波算法.是在2014年由Joao F. Henriques, Rui Caseiro, Pedro Martins ...

  8. Nginx的虚拟主机

    1.虚拟主机的概念和类型 1.1 概念: 所谓的虚拟主机,在web服务里面就是一个独立的网站站点,这个站点对应独立的域名(也有可能是IP或者端口),具有独立的程序和资源目录,可以独立的对外提供服务. ...

  9. StretchBlt和StretchDIBits

    StretchBlt:从源矩形中复制一个位图到目标矩形,必要时按目标设备设置的模式进行图像的拉伸或压缩,如果目标设备是窗口DC,则意味着在窗口绘制位图,大致的使用代码如下: void DrawImag ...

  10. InteliiJ IDEA的安装配置与简单使用

    小Alan前段时间一直在家里搬砖,已经很久没有接触技术了,从今天开始重拾技术,工欲善其事,必先利其器,以前在做Java开发的时候最常用的IDE就是Eclipse莫属了,不过随着岁月的流逝,在2016年 ...