python入門實踐四:爬取牛客網(wǎng)面試專項練習(xí)題及答案

說明:個人練手python用。
操作系統(tǒng):window10 x64
IDE:Pycharm 2017.2.2
Python版本:3.6.2

目標(biāo)

  • 爬淙埽客網(wǎng)是一個IT筆試面試的平臺,提供了很多題庫尊浓,今天我們使用python爬取其中的Java專項練習(xí)庫逞频。

步驟

1、接口抓榷俺荨:如果是爬取網(wǎng)頁苗胀,前后端分離的項目可以抓取接口,如果沒有分離瓦堵,則需要爬取整個網(wǎng)頁然后使用正則篩選基协。這里我們直接抓取客戶端接口即可。
2菇用、模擬網(wǎng)絡(luò)請求澜驮,獲取數(shù)據(jù)(這里是json)
3、json解析惋鸥,題目格式調(diào)整杂穷、寫入文件

一、接口抓取

  • 工具:Fiddler
  • 對象:咆孕澹客網(wǎng)Android客戶端2.21.3.3091

通過Fiddler發(fā)現(xiàn)耐量,獲取專項練習(xí)題的接口為:

http://m.nowcoder.com/test/get-all-question?t=02436CC60E649584D5C4BBF57709E5CA&fm=android_app_2.21.3.3091&tid=10716711

這里:

  • t=02436CC60E649584D5C4BBF57709E5CA應(yīng)該是用戶身份標(biāo)識
  • tid=10716711是本次練習(xí)的編號(Java專項練習(xí)一共900多道題,每次練習(xí)會隨機組卷滤港,組卷數(shù)量為5廊蜒、10、20蜗搔、30這些劲藐,這個tid就是組出的試卷的編號)

使用Fiddler模擬請求八堡,就可以得到該tid對應(yīng)10道題目的json數(shù)據(jù)了樟凄,由于每次請求tid沒有變化,可以發(fā)現(xiàn)多次請求的json結(jié)果是一樣的,類似下面的:

{
    "data": {
        "paper": {
            ......省略部分
            "diffcult": 3,
            "questionCount": 10,
            ......省略部分
        },
        "allQuestion": [
            {
                "score": 10,
                "shielded": false,
                "question": {
                    "content": "<p>\n  <span>下列關(guān)于構(gòu)造方法不正確的是:( </span>\n  <span> )</span>\n</p>\n<p style=\"text-indent: 15.8pt;\">\n  <br>\n</p>\n<p>\n  <br>\n</p>",
                    "id": 69561,
                    "title": "下列關(guān)于構(gòu)造方法不正確的是:( )",
                    "answer": [
                        {
                            "content": "類的構(gòu)造方法和類同名",
                            "id": 111297,
                            "type": 0
                        },
                        ......省略部分
                    ],
                    ......省略部分
                },
                "pos": 1
            },
            ......省略部分
        ],
        "userAnswers": [
            {
                "userAnswer": "111300",
                "pos": 1
            },
            ......省略部分
        ]
    },
    "code": 0,
    "msg": "OK"
}

要想不一樣兄渺,就需要不一樣的tid了缝龄,發(fā)現(xiàn)生成tid的接口如下:

POST http://m.nowcoder.com/itest/request-make-paper HTTP/1.1
......省略部分request header

questionCount=10&tagIds=570&t=02436CC60E649584D5C4BBF57709E5CA&fm=android_app_2.21.3.3091&source=1

這是一個post請求,可以發(fā)現(xiàn)在request body中的questionCount就是表明了本次組卷試題的數(shù)量。

這樣思路就清晰了:

  • 根據(jù)request-make-paper接口獲取tid叔壤,這里我們指定questionCount為30
  • 根據(jù)get-all-question接口瞎饲,傳入tid參數(shù),獲取此次組卷的30道題的json數(shù)據(jù)
  • 然后分析這30道題中的字段的含義炼绘,解析嗅战、存儲即可

二、網(wǎng)絡(luò)請求

定義一個方法俺亮,用于post請求驮捍,返回響應(yīng)的內(nèi)容,如下:

def post_json_data(url, request_body):
    req = request.Request(url)
    # 根據(jù)需要設(shè)置請求頭脚曾,比如模擬瀏覽器請求設(shè)置UA东且、一些身份權(quán)限認(rèn)證字段等都會放到header里
    req.add_header('OS', 'Android')
    req.add_header('VERSION', '82')
    req.add_header('CHANNEL', '360')
    req.add_header('User-Agent', 'nowcoder android 2.21.3.3091')
    # post請求,添加request body即可
    with request.urlopen(req, data=request_body.encode('utf-8')) as f:
        if f.status == 200:
            result_json = json.loads(f.read())
            return result_json

再定義一個方法本讥,用于get請求珊泳,返回響應(yīng)的內(nèi)容,如下:

def get_json_data(url):
    req = request.Request(url)
    req.add_header('OS', 'Android')
    req.add_header('VERSION', '82')
    req.add_header('CHANNEL', '360')
    req.add_header('User-Agent', 'nowcoder android 2.21.3.3091')
    with request.urlopen(req) as f:
        if f.status == 200:
            result_json = json.loads(f.read())
            return result_json

如果把添加到request header中的這些key-value的參數(shù)組成dict拷沸,就可以通過外部傳入色查,方法中遍歷添加,上面兩個方法就可以作為工具方法了撞芍。

接下來組裝post請求的request body中的參數(shù)

data_make_paper = parse.urlencode([
    ('questionCount', '30'),
    ('tagIds', '570'),
    ('t', '02436CC60E649584D5C4BBF57709E5CA'),
    ('fm', 'android_app_2.21.3.3091'),
    ('source', '1')
])

就可以發(fā)送網(wǎng)絡(luò)請求综慎,獲取響應(yīng)數(shù)據(jù)了:

result = post_json_data('http://m.nowcoder.com/itest/request-make-paper', data_make_paper)
url_get_questions = "http://m.nowcoder.com/test/get-all-question" + \
                    "?t=02436CC60E649584D5C4BBF57709E5CA&fm=android_app_2.21.3.3091&tid=" + \
                    str(result['data'])

需要注意的是,需要引入request和parse模塊:

from urllib import request,parse

三勤庐、json解析示惊,題目格式調(diào)整、寫入文件

先定義一個寫入文件的方法愉镰,這里我們需要追加的形式寫米罚,也即后面寫入的內(nèi)容不能覆蓋前面已經(jīng)寫入的:

def write_text(path, text, mode='a'):
    with open(path, mode=mode, encoding="utf-8") as f:
        f.write(text)
        f.write("<br>")

mode = 'a'就表示追加的形式寫入。

接下來就是json解析丈探、添加一下格式(如題目編號录择,選項編號,題與題之間的空行等)碗降、然后寫入文件了隘竭,直接看代碼:

all_questions = get_json_data(url_get_questions)['data']['allQuestion']
# 題號信息,由于獲取的題目沒有編號
n = 1
# 提取出來方便修改讼渊,如果有明確的題目數(shù)量动看,可以嵌套一層循環(huán)來循環(huán)獲取n套題。這里我們獲取1套題作為演示
# 之所以寫入到html文件爪幻,是因為讀取的題目中含有html的格式信息
questions_name = "第1套.html"
questions_answer_name = "第1套答案.html"
for item_question in all_questions:
    # 獲取題干信息
    question = item_question['question']
    question_type = ['(單選題)', '(不定項選擇題)']
    # 寫入題目信息
    write_text("C://python_test/"+questions_name, str(n)+". "+question_type[question['type']-1]+question['content'], 'a')
    answer = question['answer']
    answer_option = ''
    index = 0
    for item_answer in answer:
        # 獲取選項信息
        answer_content = item_answer['content']
        answer_index_list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
        # 寫入選項信息菱皆,加入ABCD等選項編號
        write_text("C://python_test/"+questions_name, answer_index_list[index]+". "+answer_content, 'a')
        # 獲取type字段的值须误,為1表示該選項為正確答案
        answer_type = item_answer['type']
        if answer_type == 1:
            # 獲取正確答案
            answer_option += answer_index_list[index]
        index += 1
    # 每題之間留空行
    write_text("C://python_test/"+questions_name, '', 'a')
    # 寫入答案到另外一個文件中
    write_text("C://python_test/"+questions_answer_name, str(n)+"."+'答案: ' + answer_option, 'a')
    # 答案之間留空行
    write_text("C://python_test/"+questions_answer_name, '', 'a')
    # 編號自增
    n += 1

注意引入json模塊

import json

python中的json和dict直接對應(yīng),非常方便仇轻。

案例Github地址

留個作業(yè):

  • 通過抓取答題接口京痢,完成題目自動答題,保證每套題都得滿分~
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末篷店,一起剝皮案震驚了整個濱河市祭椰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疲陕,老刑警劉巖吭产,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鸭轮,居然都是意外死亡臣淤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門窃爷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邑蒋,“玉大人,你說我怎么就攤上這事按厘∫降酰” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵逮京,是天一觀的道長卿堂。 經(jīng)常有香客問我,道長懒棉,這世上最難降的妖魔是什么草描? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮策严,結(jié)果婚禮上穗慕,老公的妹妹穿的比我還像新娘。我一直安慰自己妻导,他們只是感情好逛绵,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著倔韭,像睡著了一般术浪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寿酌,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天胰苏,我揣著相機與錄音,去河邊找鬼份名。 笑死碟联,一個胖子當(dāng)著我的面吹牛妓美,可吹牛的內(nèi)容都是我干的僵腺。 我是一名探鬼主播鲤孵,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辰如!你這毒婦竟也來了普监?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤琉兜,失蹤者是張志新(化名)和其女友劉穎凯正,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豌蟋,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡廊散,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了梧疲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片允睹。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖幌氮,靈堂內(nèi)的尸體忽然破棺而出缭受,到底是詐尸還是另有隱情,我是刑警寧澤该互,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布米者,位于F島的核電站,受9級特大地震影響宇智,放射性物質(zhì)發(fā)生泄漏蔓搞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一随橘、第九天 我趴在偏房一處隱蔽的房頂上張望败明。 院中可真熱鬧,春花似錦太防、人聲如沸妻顶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讳嘱。三九已至,卻和暖如春酿愧,著一層夾襖步出監(jiān)牢的瞬間沥潭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工嬉挡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钝鸽,地道東北人汇恤。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像拔恰,于是被迫代替她去往敵國和親因谎。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理颜懊,服務(wù)發(fā)現(xiàn)财岔,斷路器,智...
    卡卡羅2017閱讀 134,702評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法河爹,類相關(guān)的語法匠璧,內(nèi)部類的語法,繼承相關(guān)的語法咸这,異常的語法夷恍,線程的語...
    子非魚_t_閱讀 31,664評論 18 399
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,293評論 25 707
  • 寒月掛柳梢,冷水映燈影媳维。 短橋穿腸風(fēng)酿雪,殘雪靜寂嶺。 休問何處來侨艾,不言何處往执虹。 不似游人閑,不似路人歸唠梨。 ——柳子
    五柳散人閱讀 301評論 0 3