您好,登錄后才能下訂單哦!
最近一周一直在幫家里小弟看高考志愿,所以更新的沒那么頻繁了,請大家見諒。
在看各高校的往年分數時,忍不住手癢,想著能不能給它爬下來?哈哈,說干就干!
之前無意中在這個網站發現有各個高校的歷年錄取分數線:https://gkcx.eol.cn。
我們的目標是用 Python 將下面頁面的數據導出到 Excel:
這個頁面的 URL 是:https://gkcx.eol.cn/schoolhtm/schoolTemple/school160.htm,顯然是需要一個 school_id
拼接而成的,那么如何獲取這個 school_id 呢?
除非想辦法爬取到所有院校的 school_id,這里我想著是從上面圖中的搜索框進入:
這樣,整體的業務流程我們就理清楚了:
按下 F12
,可以看出搜索調用的 URL 是:https://gkcx.eol.cn/soudaxue/queryschool.html?&keyWord1=南京郵電大學
,但是我們發現該請求的 response 里并沒有高校列表,所以猜測這里是有二次數據請求獲取到高校的列表,然后解析顯示到頁面的。
順著請求流,我們看到了這么一個請求:
并且它的 response 剛好是一個包含高校信息的 json,到這里應該還是順利的,我們只要從這個 json 里解析出我們想要的東西,然后繼續后面的步驟就可以了。要注意該請求的 Referer
。
但是在解析這個 json 時會遇到一個小問題,返回的數據格式是這樣的:
({
"totalRecord": {"num": "2"},
"school": [
{
"schoolid": "160",
"schoolname": "南京郵電大學",
...
});
它是被 ();
包圍著的,不是一個合法的 json 數據,這里需要對其進行處理后才能解析 json:
# 返回數據包含 ();,需要特殊處理
text = ((response.text).split(');',1)[0]).split('(',1)[1]
j = json.loads(text)
學校的詳情頁面是:https://gkcx.eol.cn/schoolhtm/schoolTemple/school160.htm,同樣的套路,在點擊后 response 里并沒有分數線數據,我想也是二次請求吧,果然在請求流里找到了這個:
這里的兩個請求剛好將高校的每年分數線和各專業的分數線以 XML 的格式返回,Very Good!
下面要做的就是 XML 解析啦。
這里我們使用 xml.etree.ElementTree
來解析 XML:
<areapionts>
<areapiont>
<year>2017</year>
<specialname>軟件工程(嵌入式培養)</specialname>
<maxfs>369</maxfs>
<varfs>366</varfs>
<minfs>364</minfs>
<pc>一批</pc>
<stype>理科</stype>
</areapiont>
由于數據比較規整,解析也很簡單:
areapionts = ET.fromstring(response.text)
for areapiont in areapionts:
print(areapiont.find('year').text)
print(areapiont.find('specialname').text)
Excel 的寫入需要借助于 openpyxl
模塊。
>>> import openpyxl
>>> wb = openpyxl.Workbook()
# 初始時會生成一個 sheet 頁
>>> wb.sheetnames
['Sheet']
# 創建 sheet 頁
>>> wb.create_sheet(index=0,title='First')
<Worksheet "First">
# 獲取所有 sheet 頁
>>> wb.sheetnames
['First', 'Sheet']
# 刪除 sheet 頁
>>> wb.remove(wb['Sheet'])
>>> wb.sheetnames
['First']
>>> sheet = wb['First']
# 設置單元格
>>> sheet['A1'] = '省份'
>>> sheet['B1'] = '學校'
# 設置指定的單元格
>>> sheet.cell(1,3).value='test'
>>> wb.save('test.xlsx')
def gen_excel(school,xml,wb):
sheet = wb.create_sheet(title='各專業歷年錄取分數線')
sheet.column_dimensions['B'].width = 40
sheet['A1'] = '年份'
sheet['B1'] = '專業'
sheet['C1'] = '最高分'
sheet['D1'] = '平均分'
sheet['E1'] = '最低分'
sheet['F1'] = '批次'
sheet['G1'] = '錄取批次'
areapionts = ET.fromstring(xml)
column = 1
for areapiont in areapionts:
column += 1
sheet.cell(column,1).value = areapiont.find('year').text
sheet.cell(column,2).value = areapiont.find('specialname').text
sheet.cell(column,3).value = areapiont.find('maxfs').text
sheet.cell(column,4).value = areapiont.find('varfs').text
sheet.cell(column,5).value = areapiont.find('minfs').text
sheet.cell(column,6).value = areapiont.find('pc').text
sheet.cell(column,7).value = areapiont.find('stype').text
wb.save('{}.xlsx'.format(school['schoolname']))
$ python gkcx.py
Please the school name:南京郵電大學
共檢索到 2 個高校:['南京郵電大學', '南京郵電大學通達學院']
數據獲取完成,已下載到腳本目錄
結果看著還可以,但是還是有問題的,因為各省的分數線肯定是不一樣的,這里默認檢索出的是學校所在省的分數線,因此若要獲取在其他省的分數線,還需要進一步處理,有興趣的同學不妨動手試一下。后臺回復「高考」可以獲取源碼。
最近搜集到慕課網視頻,視頻內容涵蓋 Python、Java、PHP、前端、小程序、算法、架構、數據庫等等!關注本公眾號,后臺回復「慕課網」即可獲取下載地址。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。