刚学完Python和爬虫,想实践一下,于是选定目标为这个学期使用的在线编程网站
网站如图,要爬取的是第二部分,Python语言练习
**
思路分析:
**
课程看的是MOOC上北京理工大学嵩天老师的课程,这个网站与课程中给出的几个实例有所不同。该网站需要用异步XHR爬取。
- 由于在爬取该网站的过程中没有涉及到对标签的解析,或者遍历,所以并不需要使用BeautifulSoup库,使用request库获取网页内容即可。cookie需要手动复制,因为它会定期更新,初学,还没有把自动更新cookie这个功能加进去。
- 将得到的数据进行提取。
在线编程页面的数据主要以json格式进行传输,了解json的格式后,仔细观察返回的数据的固定格式,可以对题目,内容以及完成的代码进行提取(提取涉及到字典和列表的访问)。
并将题目,内容以及代码分别放入列表,供保存文件时使用。 - 将数据按照一题一文档的形式写入磁盘。每个文件的文件名和内容均是从第2步中得到。
以爬取淘宝商品信息为例:
淘宝页面显示的商品信息,在页面源代码中均可以搜索到。
如图
但是阿尔法的网页源代码什么都没有,如图:
网页源代码中没有相关代码
原因: 用ajax异步请求数据的网页要采用异步XHR爬取
浏览器:检查——Network——XHR,可以看到代码名的拼音:yang-hui-san-jiao,以及它的类型Type:xhr
点击拼音名,可以查看到异步请求的URL和cookie,这里的URL与地址栏中的URL不同,用于访问获得真正需要的数据,通过修改 “lesson/ ” 后面的内容可以访问到每道题的页面
在检查的Preview选项中也可以看到我们真正需要的数据,内容如图,以JSON形式传输
信息标记之一:JSON(JavaScript Object Notation)采用键值对形式存储信息,示例:
"name":"value"
"name":["value","value1"]
"name":{
"newname":"value",
"oldname":"value2"
}
对json数据进行解析可以在这个网站进行:JSON在线解析及格式化验证,它可以将数据更直观的展示出来*
在这里可以看到id,title,content和correctAnswer,
- id
id用于与“http://www.alphacoding.cn/api/learning/v3/79/lesson/”进行拼接后访问每道题对应网站
拼接后遍历所有网址,如图:
- title
title中保存了题目 - content
content中保存了题目要求 - correctAnswer
correctAnswer中保存了已完成的答案,如图:
代码部分:CrawlAlphaCoding.py
#coding=utf-8
import json
import os
import requests
def getHTMLText(url):#获取网页内容
try:
kv = {'cookie': 'AC-Token=ddN-XvrPVAmSA9zEGfjLwhoOQzYFzSZU; AC-Token.sig=Jbq6_JXLzl0RuRQxxnMFvMz9blQ',
'user-agent': 'Mozilla/5.0'}
r = requests.get(url, headers=kv, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
demo = r.text
return demo
except:
return ""
def grabCode(demo):
jsonstr = json.loads(demo)
# print(type(jsonstr))
#输出标题
print("题目".center(40,'*'))
print(jsonstr['data']['lesson']['title'])#对字典进行访问
#输出内容
print("要求".center(40,'*'))
print(jsonstr['data']['lesson']['exercises'][0]['description']['content'])#对字典和列表进行访问
#输出代码
print("代码".center(40,'*'))
print(jsonstr['data']['lesson']['exercises'][0]['files'][0]['correctAnswer'])
#将题目,内容,代码拼接,之后存入文件
code = "题目".center(40,'*')+"\n"+jsonstr['data']['lesson']['title']+"\n"+"要求".center(20,'*')+"\n"+jsonstr['data']['lesson']['exercises'][0]['description']['content']+"\n"+"代码".center(20,'*')+"\n"+\
jsonstr['data']['lesson']['exercises'][0]['files'][0]['correctAnswer']
return code
url = 'http://www.alphacoding.cn/api/courses/v3/79/chapterDetail'#获取章节信息,包含id和title
jsonstr = json.loads(getHTMLText(url))
print(type(jsonstr))
id = []#定义列表,将id和title存入列表,便于保存文件时的使用
title = []
rawdate = jsonstr['data']['chapters']
for i in rawdate:#第一个for循环,遍历章节,用于做url后缀访问网站
# print(type(i))
# print(len(i))#
for a in range(len(i['lessons'])):#第二个for循环,遍历题目,用作文件名
# print(len(i['lessons']))
id.append(i['lessons'][a]['lessonId'])
title.append(i['lessons'][a]['title'])
def saveText(i,enddate):
root = "d:/CrawlAlphaCoding/"
textname = root + title[i] + ".txt"
if not os.path.exists(root):#目录不存在则创建
os.makedirs(root)
if not os.path.exists(textname):#文件不存在则创建
f = open(textname, "w+",encoding="utf-8")#不加encoding会导致部分文件无内容写入
f.write(enddate)
else:
print("文件已存在")
def main():
for i in range(len(id)):
try:#导学部分没有代码,会访问出错,使用try/except处理异常
print("http://www.alphacoding.cn/api/learning/v3/79/lesson/"+id[i])
realurl = "http://www.alphacoding.cn/api/learning/v3/79/lesson/"+id[i]#异步请求URL与id拼接后,对网站进行遍历
rawdate = getHTMLText(realurl)
# print(rawdate)
print(grabCode(rawdate))
saveText(i, grabCode(rawdate))
except:
print("章节导航没有代码")
main()
运行效果
Pycharm运行结果
成功保存文件并写入