要求
第一部分:
请分析作业页面,爬取已提交作业信息,并生成已提交作业名单,保存为英文逗号分隔的csv文件。文件名为:hwlist.csv 。
文件内容范例如下形式:
学号,姓名,作业标题,作业提交时间,作业URL
20194010101,张三,羊车门作业,2018-11-13 23:47:36.8,
http://www.cnblogs.com/sninius/p/12345678.html
第二部分:
在生成的 hwlist.csv 文件的同文件夹下,创建一个名为 hwFolder 文件夹,为每一个已提交作业的同学,新建一个以该生学号命名的文件夹,将其作业网页爬去下来,并将该网页文件存以学生学号为名,“.html”为扩展名放在该生学号文件夹中。
正题
之前打过CTF比赛,完成这样的爬虫还是挺简单的。以爬取羊车门问题的作业为例,以下是我解决这个问题的思路,欢迎大家向我提出问题,或者指出错误。
我们将需要爬取的内容在页面中找到,他是下图这样的:
分析一下他们的代码,我在浏览器中对应位置右键,然后点击检查元素,可以找到对应部分的代码。但是,直接查看当前网页的源码发现,里面并没有对应的代码。我猜测这里是根据服务器上的数据动态生成的这部分代码,所以我们需要找到数据文件,以便向服务器申请,得到这部分资源。
在刚才查看元素的地方接着找数据文件,在Network里面的文件中很顺利的就找到了,并在报文中拿到了URL和请求方法。
查看一下这个文件发现是JSON文件,那样的话难度就又降低了,因为Python中有json库,解析json的能力很强。可以直接将json转换为字典和列表类型。
这时候我们爬取需要的信息的准备工作可以说是结束了,我们拿到了数据的URL,并且知道了数据类型。于是,我们只需要用requests库爬一下这个页面,然后用json解析一下,并且筛选有用的信息就好了。
(没用到BeautifulSoup和re库有点小失落)
接下来就是创建文件,就没有什么难度了。只是在每个学生创建文件的时候注意一下,创建好以后及时的回到上层目录,否则,可能会让文件一层层的嵌套下去。
代码
# -*- coding:utf-8 -*- import requests import json import os #抓取页面 url = 'https://edu.cnblogs.com/Homework/GetAnswers?homeworkId=2420&_=1542959851766' try: r = requests.get(url,timeout=20) r.raise_for_status() r.encoding = r.apparent_encoding except: print('网络异常,请重试') #利用json拿到数据列表,每个列表元素都是字典 datas = json.loads(r.text)['data'] result = "" #数据处理 for data in datas: result += data['StudentNo']+','+data['RealName']+','+data['DateAdded']+','+data['Title']+','+data['Url']+'\n' #写入文件 with open('hwlist.csv','w') as f: f.write(result) #创建文件夹hwFolder os.mkdir('hwFolder') os.chdir('hwFolder') #创建每个学生的作业文件 for data in datas: #创建目录 os.mkdir(data['StudentNo']) os.chdir(data['StudentNo']) #抓取页面 try: webmsg = requests.get(data['Url'],timeout=20) webmsg.raise_for_status() webmsg.encoding = webmsg.apparent_encoding except: print('网络异常,请重试') #保存抓到的页面 with open(data['StudentNo']+'.html','wb') as f: f.write(webmsg.content) os.chdir(os.path.pardir)
结果展示
上图是hwlist.csv文件的部分结果(Excel下打开)
以上是为每个学生创建的文件和文件夹的结果,让我打开一个HTML文件进行查看,看看爬取的成果:
爬到的内容是没有问题的,只是一些图片和排版不太正确。这是因为我只爬取了HTML页面,没有爬取图片等资源的结果,后续如果有机会我会一并爬取整个页面的所有资源。