刚学完Python和爬虫,想实践一下,于是选定目标为这个学期使用的在线编程网站

网站如图,要爬取的是第二部分,Python语言练习

python 获取argument python获取xhr_python


**

思路分析:

**
课程看的是MOOC上北京理工大学嵩天老师的课程,这个网站与课程中给出的几个实例有所不同。该网站需要用异步XHR爬取。

  1. 由于在爬取该网站的过程中没有涉及到对标签的解析,或者遍历,所以并不需要使用BeautifulSoup库,使用request库获取网页内容即可。cookie需要手动复制,因为它会定期更新,初学,还没有把自动更新cookie这个功能加进去。
  2. 将得到的数据进行提取。
    在线编程页面的数据主要以json格式进行传输,了解json的格式后,仔细观察返回的数据的固定格式,可以对题目,内容以及完成的代码进行提取(提取涉及到字典和列表的访问)。
    并将题目,内容以及代码分别放入列表,供保存文件时使用。
  3. 将数据按照一题一文档的形式写入磁盘。每个文件的文件名和内容均是从第2步中得到。

以爬取淘宝商品信息为例:

淘宝页面显示的商品信息,在页面源代码中均可以搜索到。

如图

python 获取argument python获取xhr_数据_02


python 获取argument python获取xhr_ci_03


但是阿尔法的网页源代码什么都没有,如图:

python 获取argument python获取xhr_python_04


网页源代码中没有相关代码

python 获取argument python获取xhr_数据_05


原因: 用ajax异步请求数据的网页要采用异步XHR爬取

python 获取argument python获取xhr_ci_06


浏览器:检查——Network——XHR,可以看到代码名的拼音:yang-hui-san-jiao,以及它的类型Type:xhr

python 获取argument python获取xhr_数据_07


点击拼音名,可以查看到异步请求的URL和cookie,这里的URL与地址栏中的URL不同,用于访问获得真正需要的数据,通过修改 “lesson/ ” 后面的内容可以访问到每道题的页面

python 获取argument python获取xhr_python_08


在检查的Preview选项中也可以看到我们真正需要的数据,内容如图,以JSON形式传输

python 获取argument python获取xhr_python 获取argument_09


信息标记之一:JSON(JavaScript Object Notation)采用键值对形式存储信息,示例:

"name":"value"
"name":["value","value1"]
"name":{
	"newname":"value",
	"oldname":"value2"
		}

对json数据进行解析可以在这个网站进行:JSON在线解析及格式化验证,它可以将数据更直观的展示出来*

python 获取argument python获取xhr_python 获取argument_10


在这里可以看到id,title,content和correctAnswer,

  1. id

id用于与“http://www.alphacoding.cn/api/learning/v3/79/lesson/”进行拼接后访问每道题对应网站

python 获取argument python获取xhr_python 获取argument_11


拼接后遍历所有网址,如图:

python 获取argument python获取xhr_数据_12

  1. title
    title中保存了题目
  2. python 获取argument python获取xhr_数据_13

  3. content
    content中保存了题目要求
  4. python 获取argument python获取xhr_python 获取argument_14

  5. correctAnswer
    correctAnswer中保存了已完成的答案,如图:
  6. python 获取argument python获取xhr_ci_15

代码部分: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运行结果

python 获取argument python获取xhr_json_16


成功保存文件并写入

python 获取argument python获取xhr_python 获取argument_17


python 获取argument python获取xhr_json_18