爬取学校教务处网站,提取并保存信息

最近开始用简书记录学习过程的点滴。等以后自己学会建博客再移到博客上去吧~

工具:
python3.6.3
requests
BeautifulSoup
xlwt

爬取学校教务处
学了python基础语法,requests和beautsoup,没有练手过,遂到教务处一展拳脚。我学校的教务处登录比较简单,没有验证码,然而我还是不会用post。。。。。

1:构造请求
这里需要伪造一下浏览器:
这里尽显我爬虫渣本色,直接在谷歌浏览器里开发者工具中复制的header

header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}

此外,登录需要密码账号,我试图用requests的post方法,构建账号密码信息,然而一知半解,在此记录过程,希望有高手解答:

a.打开登录页面-F12-Network抓包,如图:


image.png

b. 抓包
抓包还看了不少博客,学的三脚猫的功夫:先故意输错密码试试看


image.png

可以看到network中抓取到数据流,点开Form Data, userName和pwd应该就是账号和密码,但是pwd后面这串是什么鬼啊???加密???还有这个sign后面那串数字,我也看不懂,所以post方法暂时行不通,可以留着以后慢慢研究,或者有大神解释解释那是极好的。

穷则思变,变则通达,post不行,我就不学了吗?那肯定不会。在网上看到了另外一招,对新手及其友好的,利用cookies进行登录。

a. 输入账号密码,登录教务处页面,还是打开网络监听F12-Network,点击第一个选项,它是此页中第一个数据流(或者其他叫法,我极其不专业。。。),在右侧找到cookies,如下图


image.png

关于cookies的原理我也不懂,看文章说是用户与服务器之间的一种凭证,应该就是短时间生成的一种凭证,只要这个凭证有效,那么用户就可以不用登陆就可以访问服务器上面的数据。看它这么乱,应该是用方法加密了,暂且就这么理解吧。

b. 复制这段cookies,我们就可以制作cookies了。使用如下代码:

cookies = {}
raw_cookies = "ASP.NET_SessionId=2gq0mryer************; UserTokeID=f716cffe-************-a84d-**********c"
for line in raw_cookies.split(';'): #用';'对字符串分割
        key, value = line.split('=', 1)
        cookies[key] = value

这个方法我是网上学到的,不过它的作用其实就是将原生的cookies构造成以键值对形式的字典,所以你也可以直接这样:

cookies = {'ASP.NET_SessionId': '2gq0mryer************', 'UserTokeID': 'f716cffe-************-a84d-**********c'}

这样手动将复制下来的raw_cookies构造成cookies。

接下来是获取URL,我们打开成绩页面,同样也是用F12去捕捉成绩页面的URL:



或者其实可以直接从网址那里复制???不是很懂,因为有网友说其实获取真实URL会有点麻烦。。。这里也要回头复习,什么是真实URL?怎么获取?嗯,记一下。

到这里我们已经把所有请求页面要包含的信息都准备好,可以开始写请求代码了。我用的是requests库,感觉要比urllib2方便。

import requests
from bs4 import BeautifulSoup

header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}
cookies = {}
raw_cookies = "ASP.NET_SessionId=2gq0mryer************; UserTokeID=f716cffe-************-a84d-**********c"
for line in raw_cookies.split(';'): #用';'对字符串分割
        key, value = line.split('=', 1)
        cookies[key] = value
url = "http://202.115.133.***:805/********/Score/ScoreList.aspx"

r = requests.get(url, headers = header, cookies = cookies)

这样我们就完成了请求,接下来解析页面。

2:解析页面
打开成绩页面,F12下看Element选项,或者网页源代码,我们可以看出成绩页面的结构:如下图:


image.png

右键审查元素,定位到元素标签。哇,这么多<li class="item">...</li>标签,应该就是每门课的成绩信息了。我们点开具体看一下:


image.png

果然,没毛病老铁。

接下来就好办了,思路是:用靓汤找到所有的<li class="item">...</li>标签,然后循对每一个<li class="item">...</li>里面的信息提取。嗯,上代码:

soup = BeautifulSoup(r.text, "html.parser")
items = soup.findAll('li', attrs = {'class': 'item'}
for item in items:
        print(item.text)

我们先来试试看输入结果:


image.png

你妹!!!什么鬼?!!!这一大堆的空格我可不能输进Excel啊!!!
试试用split()切开:

soup = BeautifulSoup(r.text, "html.parser")
items = soup.findAll('li', attrs = {'class': 'item'}
for item in items:
        print(item.text.split())
out:
image.png

嗯~~~很好,列表形式的数据就好操作多了。为了能更加愉快地玩耍,我们可以把这些列表全放到一个新的列表里:

data_list = []
for item in items:
        data_list.append(item.text.split())

看看输出:

print(data_list)
image.png

很好,接下来就只要把数据写进Excel里面就成啦

3:保存数据
写入Excel操作我用到了xlwt,安装这个库也是有点小坑,具体解决方案网上有很多,不再赘述。上代码:

book = xlwt.Workbook()
sheet1 = book.add_sheet('sheet1', cell_overwrite_ok = True)
#列表的每一行写入一门课成绩,最开始的行为0行,写入表格头:
heads = ['学期', '课程编码', '课程名称', '教师', '学分', '成绩', '成绩类型', '绩点', '入库人', '入库时间']
#这里write方法接受3个参数,分别为行、列、值。表格头部信息在第0行
i = 0
for head in heades:
        #依次将heades列表的每一个元素写入表格中
        sheet1.write(0, i, head)
        i += 1
#从第1行开始写入成绩信息
m = 1
#对大列表里每一个小列表进行遍历,小列表保存有一门课的成绩信息,这样就能把所有课程成绩信息循环到。
for list in data_list:
        n = 0
        #对小列表里每个元素进行遍历
        for info in list:
                #将每个元素写入表格
                sheet1.write(m, n, info)
                n += 1
        m += 1
book.save('grade.xls')

这样全部代码就完成啦!下面是完整代码,本水笔代码代码像屎一样,没有一丁点封装。。。。。后面有时间再慢慢优化

import requests
from bs4 import BeautifulSoup
import xlwt

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
raw_cookies = "ASP.NET_SessionId=2gq0mryer0o34wrmurek2dm3; UserTokeID=37efd17b-5a15-409f-93c5-8f9566d2b21d"

cookie = {}
for line in raw_cookies.split(';'):
    key, value = line.split("=", 1)
    cookie[key] = value
url = "http://202.115.133.173:805/SearchInfo/Score/ScoreList.aspx"
r = requests.get(url, headers=header, cookies = cookie)
r.encoding = 'utf8'

data_list = []
soup = BeautifulSoup(r.text, "html.parser")
items = soup.find_all('li', attrs={'class': 'item'})
for item in items:
    data_list.append(items.text.split())

book = xlwt.Workbook()
sheet1 = book.add_sheet('sheet1', cell_overwrite_ok = True)
heads = ['学期', '课程编码', '课程名称', '教师', '学分', '成绩', '成绩类型', '绩点', '入库人', '入库时间']
i = 0
for head in heads:
    sheet1.write(0, i, head)
    i += 1

m = 1
for list in data_list:
    n = 0
    for data in list:
        sheet1.write(m, n, data)
        n += 1
    m += 1
book.save("chenzhida.xls")
print("录入成功")

成果如下:


image.png

遗留问题:
有些课程的信息不全,比如没有教师的名字等等,这样录进Excel的时候信息会对不上表头。应该可以用某种替换方法,给空格占个位置,这样录进去的格式就能对的上表头。后面再处理吧~

以下是本次爬取过程中遇到的一些坑,还有困惑,写下来提醒自己以后要解决:

  1. 使用cookies模拟登录自然会省事点,但是由于这个凭证只能短期有效,当需要爬取数据很多的时候,可能需要爬取十几天或者更久,这时cookies就不好用了,容易挂掉。这里需要学习post,学习分析账号密码提交,要是有加密怎么破解?遇到验证码怎么办?FROM DATA中每一项数据代表什么?遇到动态页面怎么破?(有大神教吗?)
  2. 如何获取真实URL,真实URL是什么?
  3. 表格数据有缺失怎么破
  4. 保存数据到本地。要学习常用的mongoDB。
  5. 学习其他的解析工具,Xpath
  6. 学习scrapy。

另外,此次保存数据还花了老子大部分时间,记录一下犯蠢的过程:
一开始我的思路是,把所有的课程成绩信息提取出来,放到一个总的表格里,然而当我实际做的时候,我发现:

items = soup.findAll(r.text, "html.parser)
data_list = []
for item in items:
        data_list.append(item.text)
        print(data_list)

返回的是:



后来发现是输出的地方错了:应该是

items = soup.findAll(r.text, "html.parser)
data_list = []
for item in items:
        data_list.append(item.text)
print(data_list)

for循环没掌握好。。。。
但是这样输出的是:


image.png

还是不行呀,这些“ \xa0\r\n,\n\r\n ”是什么鬼???(其实可以用在末尾追加.spilt()方法,可以实现去掉空格和换行符)

然后我又想到了可不可以用正则表达式提取内容?把所有内容提取出来放到一个表格中,和原来不同的是,这里大表格里面是没有小表格的。我们可以取10个元素取10个元素这样去做小表格。
又开始折腾了:

infos = re.findall(r'<div.*?">(.*?)</div>', str(items))
print(infos)

结果:


image.png

emmmmmm......exo me????
后来仔细一看网页源代码:


image.png

哦,原来有空格,而 . 是除了空格以外的任意字符,一般都要加re.S
infos = re.findall(r'<div.*?">(.*?)</div>', str(items), re.S)
print(infos)

结果:


image.png

what the 你妹!这不和原来一样了吗?不过确实是一个大表格,但是
\xa0\r\n \r\n 肿么破?机智的我想到用replace()试试看:

infos = re.findall(r'<div.*?">(.*?)</div>', str(items), re.S)
for info in infos:
        print(str(info).replace('\xa0\r\n', '').replace('\r\n', '').strip())
image.png

我好像发现了什么!!!原来的遗留问题貌似可以解决的!!!

list = []
infos = re.findall(r'<div.*?">(.*?)</div>', str(items), re.S)
for info in infos:
    list.append(str(info).replace('\xa0\r\n', '').replace('\r\n', '').strip())
#把list按照每次取10个的数量,做成小表格,然后把这些小表格添加到new_list里面方便操作,这样的好处是,会把缺失信息的地方给站位,后面录进Excel的时候就不会对不上表头。
new_list = [list[i: i+10] for i in range(0, len(list), 10)]
print(new_list)

结果:


image.png


哈哈哈那我直接放完整代码了

# -*- coding: utf-8 -*-
import requests
import  re
from bs4 import BeautifulSoup
import xlwt

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
raw_cookies = "ASP.NET_SessionId=2gq0mryer0o34wrmurek2dm3; UserTokeID=6412ebc3-5fde-44f5-b5e0-d0de28125591"
url = "http://202.115.133.173:805/SearchInfo/Score/ScoreList.aspx"
cookies = {}
for line in raw_cookies.split(";"):
    key, value = line.split("=", 1)
    cookies[key] = value

r = requests.get(url, headers = header, cookies = cookies)
print(r.status_code)
r.encoding = 'utf8'

data_list = []
soup = BeautifulSoup(r.text, "html.parser")
items = soup.find_all('li', attrs = {'class': 'item'})

list = []
infos = re.findall(r'<div.*?">(.*?)</div>', str(items), re.S)
for info in infos:
    list.append(str(info).replace('\xa0\r\n', '').replace('\r\n', '').strip())
new_list = [list[i: i+10] for i in range(0, len(list), 10)]
print(new_list)

book = xlwt.Workbook()
sheet1 = book.add_sheet('shee1', cell_overwrite_ok=True)

heads = ['学期', '课程编码', '课程名称', '教师', '学分', '成绩', '成绩类型', '绩点', '入库人', '入库时间']
s = 0
for head in heads:
    sheet1.write(0, s, head)
    s += 1

m = 1
for lists in new_list:
    n = 0
    for data in lists:
        sheet1.write(m, n, data)
        n += 1
    m += 1
book.save("stander.xls")
print("录入成功")

成果:


image.png

这样有些没有信息的地方也可以用空白来站位。
finish!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 22年12月更新:个人网站关停,如果仍旧对旧教程有兴趣参考 Github 的markdown内容[https://...
    tangyefei阅读 35,170评论 22 257
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,848评论 25 707
  • 文/陌客 入夜之后,外面突然就下起了大雨。电闪雷鸣,好不狼狈。同宿舍的哥们,急匆匆赶回,一口一个您,听着我一身鸡皮...
    画子归阅读 288评论 0 0
  • 我喜欢的样子你都有,我们单独在一起的时候或者在网上的时候无话不谈,但就是到了生活中,遇到认识的人的时候就变得慌张不...
    天霸楠阅读 198评论 0 0