爬取學(xué)校教務(wù)處網(wǎng)站掺冠,提取并保存信息

最近開始用簡書記錄學(xué)習(xí)過程的點(diǎn)滴。等以后自己學(xué)會(huì)建博客再移到博客上去吧~

工具:
python3.6.3
requests
BeautifulSoup
xlwt

爬取學(xué)校教務(wù)處
學(xué)了python基礎(chǔ)語法码党,requests和beautsoup赫舒,沒有練手過,遂到教務(wù)處一展拳腳闽瓢。我學(xué)校的教務(wù)處登錄比較簡單接癌,沒有驗(yàn)證碼,然而我還是不會(huì)用post扣讼。缺猛。。椭符。荔燎。

1:構(gòu)造請(qǐng)求
這里需要偽造一下瀏覽器:
這里盡顯我爬蟲渣本色,直接在谷歌瀏覽器里開發(fā)者工具中復(fù)制的header

header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}

此外销钝,登錄需要密碼賬號(hào)有咨,我試圖用requests的post方法,構(gòu)建賬號(hào)密碼信息蒸健,然而一知半解座享,在此記錄過程,希望有高手解答:

a.打開登錄頁面-F12-Network抓包似忧,如圖:


image.png

b. 抓包
抓包還看了不少博客渣叛,學(xué)的三腳貓的功夫:先故意輸錯(cuò)密碼試試看


image.png

可以看到network中抓取到數(shù)據(jù)流,點(diǎn)開Form Data, userName和pwd應(yīng)該就是賬號(hào)和密碼盯捌,但是pwd后面這串是什么鬼按狙谩?饺著?箫攀?加密?幼衰?靴跛?還有這個(gè)sign后面那串?dāng)?shù)字,我也看不懂塑顺,所以post方法暫時(shí)行不通汤求,可以留著以后慢慢研究俏险,或者有大神解釋解釋那是極好的严拒。

窮則思變扬绪,變則通達(dá),post不行裤唠,我就不學(xué)了嗎挤牛?那肯定不會(huì)。在網(wǎng)上看到了另外一招种蘸,對(duì)新手及其友好的墓赴,利用cookies進(jìn)行登錄。

a. 輸入賬號(hào)密碼航瞭,登錄教務(wù)處頁面诫硕,還是打開網(wǎng)絡(luò)監(jiān)聽F12-Network,點(diǎn)擊第一個(gè)選項(xiàng)刊侯,它是此頁中第一個(gè)數(shù)據(jù)流(或者其他叫法章办,我極其不專業(yè)。滨彻。藕届。),在右側(cè)找到cookies亭饵,如下圖


image.png

關(guān)于cookies的原理我也不懂休偶,看文章說是用戶與服務(wù)器之間的一種憑證,應(yīng)該就是短時(shí)間生成的一種憑證辜羊,只要這個(gè)憑證有效踏兜,那么用戶就可以不用登陸就可以訪問服務(wù)器上面的數(shù)據(jù)“送海看它這么亂庇麦,應(yīng)該是用方法加密了,暫且就這么理解吧喜德。

b. 復(fù)制這段cookies山橄,我們就可以制作cookies了。使用如下代碼:

cookies = {}
raw_cookies = "ASP.NET_SessionId=2gq0mryer************; UserTokeID=f716cffe-************-a84d-**********c"
for line in raw_cookies.split(';'): #用';'對(duì)字符串分割
        key, value = line.split('=', 1)
        cookies[key] = value

這個(gè)方法我是網(wǎng)上學(xué)到的舍悯,不過它的作用其實(shí)就是將原生的cookies構(gòu)造成以鍵值對(duì)形式的字典航棱,所以你也可以直接這樣:

cookies = {'ASP.NET_SessionId': '2gq0mryer************', 'UserTokeID': 'f716cffe-************-a84d-**********c'}

這樣手動(dòng)將復(fù)制下來的raw_cookies構(gòu)造成cookies。

接下來是獲取URL萌衬,我們打開成績頁面饮醇,同樣也是用F12去捕捉成績頁面的URL:



或者其實(shí)可以直接從網(wǎng)址那里復(fù)制?秕豫?朴艰?不是很懂观蓄,因?yàn)橛芯W(wǎng)友說其實(shí)獲取真實(shí)URL會(huì)有點(diǎn)麻煩。祠墅。侮穿。這里也要回頭復(fù)習(xí)被碗,什么是真實(shí)URL长赞?怎么獲认埂空民?嗯壶谒,記一下黔姜。

到這里我們已經(jīng)把所有請(qǐng)求頁面要包含的信息都準(zhǔn)備好甘有,可以開始寫請(qǐng)求代碼了律适。我用的是requests庫腔长,感覺要比urllib2方便袭祟。

import requests
from bs4 import BeautifulSoup

header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}
cookies = {}
raw_cookies = "ASP.NET_SessionId=2gq0mryer************; UserTokeID=f716cffe-************-a84d-**********c"
for line in raw_cookies.split(';'): #用';'對(duì)字符串分割
        key, value = line.split('=', 1)
        cookies[key] = value
url = "http://202.115.133.***:805/********/Score/ScoreList.aspx"

r = requests.get(url, headers = header, cookies = cookies)

這樣我們就完成了請(qǐng)求,接下來解析頁面捞附。

2:解析頁面
打開成績頁面巾乳,F(xiàn)12下看Element選項(xiàng),或者網(wǎng)頁源代碼故俐,我們可以看出成績頁面的結(jié)構(gòu):如下圖:


image.png

右鍵審查元素想鹰,定位到元素標(biāo)簽。哇药版,這么多<li class="item">...</li>標(biāo)簽辑舷,應(yīng)該就是每門課的成績信息了。我們點(diǎn)開具體看一下:


image.png

果然槽片,沒毛病老鐵何缓。

接下來就好辦了,思路是:用靚湯找到所有的<li class="item">...</li>標(biāo)簽还栓,然后循對(duì)每一個(gè)<li class="item">...</li>里面的信息提取碌廓。嗯,上代碼:

soup = BeautifulSoup(r.text, "html.parser")
items = soup.findAll('li', attrs = {'class': 'item'}
for item in items:
        print(item.text)

我們先來試試看輸入結(jié)果:


image.png

你妹J:小9绕拧!什么鬼辽聊?<涂妗!跟匆!這一大堆的空格我可不能輸進(jìn)Excel耙彀馈!B瓯邸烤蜕!
試試用split()切開:

soup = BeautifulSoup(r.text, "html.parser")
items = soup.findAll('li', attrs = {'class': 'item'}
for item in items:
        print(item.text.split())
out:
image.png

嗯~~~很好封孙,列表形式的數(shù)據(jù)就好操作多了。為了能更加愉快地玩耍讽营,我們可以把這些列表全放到一個(gè)新的列表里:

data_list = []
for item in items:
        data_list.append(item.text.split())

看看輸出:

print(data_list)
image.png

很好虎忌,接下來就只要把數(shù)據(jù)寫進(jìn)Excel里面就成啦

3:保存數(shù)據(jù)
寫入Excel操作我用到了xlwt,安裝這個(gè)庫也是有點(diǎn)小坑,具體解決方案網(wǎng)上有很多斑匪,不再贅述呐籽。上代碼:

book = xlwt.Workbook()
sheet1 = book.add_sheet('sheet1', cell_overwrite_ok = True)
#列表的每一行寫入一門課成績锋勺,最開始的行為0行蚀瘸,寫入表格頭:
heads = ['學(xué)期', '課程編碼', '課程名稱', '教師', '學(xué)分', '成績', '成績類型', '績點(diǎn)', '入庫人', '入庫時(shí)間']
#這里write方法接受3個(gè)參數(shù),分別為行庶橱、列贮勃、值。表格頭部信息在第0行
i = 0
for head in heades:
        #依次將heades列表的每一個(gè)元素寫入表格中
        sheet1.write(0, i, head)
        i += 1
#從第1行開始寫入成績信息
m = 1
#對(duì)大列表里每一個(gè)小列表進(jìn)行遍歷苏章,小列表保存有一門課的成績信息寂嘉,這樣就能把所有課程成績信息循環(huán)到。
for list in data_list:
        n = 0
        #對(duì)小列表里每個(gè)元素進(jìn)行遍歷
        for info in list:
                #將每個(gè)元素寫入表格
                sheet1.write(m, n, info)
                n += 1
        m += 1
book.save('grade.xls')

這樣全部代碼就完成啦枫绅!下面是完整代碼泉孩,本水筆代碼代碼像屎一樣,沒有一丁點(diǎn)封裝并淋。寓搬。。县耽。句喷。后面有時(shí)間再慢慢優(yōu)化

import requests
from bs4 import BeautifulSoup
import xlwt

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
raw_cookies = "ASP.NET_SessionId=2gq0mryer0o34wrmurek2dm3; UserTokeID=37efd17b-5a15-409f-93c5-8f9566d2b21d"

cookie = {}
for line in raw_cookies.split(';'):
    key, value = line.split("=", 1)
    cookie[key] = value
url = "http://202.115.133.173:805/SearchInfo/Score/ScoreList.aspx"
r = requests.get(url, headers=header, cookies = cookie)
r.encoding = 'utf8'

data_list = []
soup = BeautifulSoup(r.text, "html.parser")
items = soup.find_all('li', attrs={'class': 'item'})
for item in items:
    data_list.append(items.text.split())

book = xlwt.Workbook()
sheet1 = book.add_sheet('sheet1', cell_overwrite_ok = True)
heads = ['學(xué)期', '課程編碼', '課程名稱', '教師', '學(xué)分', '成績', '成績類型', '績點(diǎn)', '入庫人', '入庫時(shí)間']
i = 0
for head in heads:
    sheet1.write(0, i, head)
    i += 1

m = 1
for list in data_list:
    n = 0
    for data in list:
        sheet1.write(m, n, data)
        n += 1
    m += 1
book.save("chenzhida.xls")
print("錄入成功")

成果如下:


image.png

遺留問題:
有些課程的信息不全,比如沒有教師的名字等等兔毙,這樣錄進(jìn)Excel的時(shí)候信息會(huì)對(duì)不上表頭唾琼。應(yīng)該可以用某種替換方法,給空格占個(gè)位置澎剥,這樣錄進(jìn)去的格式就能對(duì)的上表頭锡溯。后面再處理吧~

以下是本次爬取過程中遇到的一些坑,還有困惑哑姚,寫下來提醒自己以后要解決:

  1. 使用cookies模擬登錄自然會(huì)省事點(diǎn)祭饭,但是由于這個(gè)憑證只能短期有效,當(dāng)需要爬取數(shù)據(jù)很多的時(shí)候蜻懦,可能需要爬取十幾天或者更久甜癞,這時(shí)cookies就不好用了,容易掛掉宛乃。這里需要學(xué)習(xí)post悠咱,學(xué)習(xí)分析賬號(hào)密碼提交蒸辆,要是有加密怎么破解?遇到驗(yàn)證碼怎么辦析既?FROM DATA中每一項(xiàng)數(shù)據(jù)代表什么躬贡?遇到動(dòng)態(tài)頁面怎么破?(有大神教嗎眼坏?)
  2. 如何獲取真實(shí)URL拂玻,真實(shí)URL是什么?
  3. 表格數(shù)據(jù)有缺失怎么破
  4. 保存數(shù)據(jù)到本地宰译。要學(xué)習(xí)常用的mongoDB檐蚜。
  5. 學(xué)習(xí)其他的解析工具,Xpath
  6. 學(xué)習(xí)scrapy沿侈。

另外闯第,此次保存數(shù)據(jù)還花了老子大部分時(shí)間,記錄一下犯蠢的過程:
一開始我的思路是缀拭,把所有的課程成績信息提取出來咳短,放到一個(gè)總的表格里,然而當(dāng)我實(shí)際做的時(shí)候蛛淋,我發(fā)現(xiàn):

items = soup.findAll(r.text, "html.parser)
data_list = []
for item in items:
        data_list.append(item.text)
        print(data_list)

返回的是:



后來發(fā)現(xiàn)是輸出的地方錯(cuò)了:應(yīng)該是

items = soup.findAll(r.text, "html.parser)
data_list = []
for item in items:
        data_list.append(item.text)
print(data_list)

for循環(huán)沒掌握好咙好。。褐荷。勾效。
但是這樣輸出的是:


image.png

還是不行呀,這些“ \xa0\r\n诚卸,\n\r\n ”是什么鬼葵第??合溺?(其實(shí)可以用在末尾追加.spilt()方法卒密,可以實(shí)現(xiàn)去掉空格和換行符)

然后我又想到了可不可以用正則表達(dá)式提取內(nèi)容?把所有內(nèi)容提取出來放到一個(gè)表格中,和原來不同的是棠赛,這里大表格里面是沒有小表格的哮奇。我們可以取10個(gè)元素取10個(gè)元素這樣去做小表格。
又開始折騰了:

infos = re.findall(r'<div.*?">(.*?)</div>', str(items))
print(infos)

結(jié)果:


image.png

emmmmmm......exo me????
后來仔細(xì)一看網(wǎng)頁源代碼:


image.png

哦睛约,原來有空格鼎俘,而 . 是除了空格以外的任意字符,一般都要加re.S
infos = re.findall(r'<div.*?">(.*?)</div>', str(items), re.S)
print(infos)

結(jié)果:


image.png

what the 你妹辩涝!這不和原來一樣了嗎贸伐?不過確實(shí)是一個(gè)大表格,但是
\xa0\r\n \r\n 腫么破怔揩?機(jī)智的我想到用replace()試試看:

infos = re.findall(r'<div.*?">(.*?)</div>', str(items), re.S)
for info in infos:
        print(str(info).replace('\xa0\r\n', '').replace('\r\n', '').strip())
image.png

我好像發(fā)現(xiàn)了什么W叫稀8俊!原來的遺留問題貌似可以解決的!!!

list = []
infos = re.findall(r'<div.*?">(.*?)</div>', str(items), re.S)
for info in infos:
    list.append(str(info).replace('\xa0\r\n', '').replace('\r\n', '').strip())
#把list按照每次取10個(gè)的數(shù)量伏伐,做成小表格宠进,然后把這些小表格添加到new_list里面方便操作,這樣的好處是藐翎,會(huì)把缺失信息的地方給站位材蹬,后面錄進(jìn)Excel的時(shí)候就不會(huì)對(duì)不上表頭。
new_list = [list[i: i+10] for i in range(0, len(list), 10)]
print(new_list)

結(jié)果:


image.png


哈哈哈那我直接放完整代碼了

# -*- coding: utf-8 -*-
import requests
import  re
from bs4 import BeautifulSoup
import xlwt

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
raw_cookies = "ASP.NET_SessionId=2gq0mryer0o34wrmurek2dm3; UserTokeID=6412ebc3-5fde-44f5-b5e0-d0de28125591"
url = "http://202.115.133.173:805/SearchInfo/Score/ScoreList.aspx"
cookies = {}
for line in raw_cookies.split(";"):
    key, value = line.split("=", 1)
    cookies[key] = value

r = requests.get(url, headers = header, cookies = cookies)
print(r.status_code)
r.encoding = 'utf8'

data_list = []
soup = BeautifulSoup(r.text, "html.parser")
items = soup.find_all('li', attrs = {'class': 'item'})

list = []
infos = re.findall(r'<div.*?">(.*?)</div>', str(items), re.S)
for info in infos:
    list.append(str(info).replace('\xa0\r\n', '').replace('\r\n', '').strip())
new_list = [list[i: i+10] for i in range(0, len(list), 10)]
print(new_list)

book = xlwt.Workbook()
sheet1 = book.add_sheet('shee1', cell_overwrite_ok=True)

heads = ['學(xué)期', '課程編碼', '課程名稱', '教師', '學(xué)分', '成績', '成績類型', '績點(diǎn)', '入庫人', '入庫時(shí)間']
s = 0
for head in heads:
    sheet1.write(0, s, head)
    s += 1

m = 1
for lists in new_list:
    n = 0
    for data in lists:
        sheet1.write(m, n, data)
        n += 1
    m += 1
book.save("stander.xls")
print("錄入成功")

成果:


image.png

這樣有些沒有信息的地方也可以用空白來站位吝镣。
finish堤器!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赤惊,隨后出現(xiàn)的幾起案子吼旧,更是在濱河造成了極大的恐慌凰锡,老刑警劉巖未舟,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異掂为,居然都是意外死亡裕膀,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門勇哗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昼扛,“玉大人,你說我怎么就攤上這事欲诺〕常” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵扰法,是天一觀的道長蛹含。 經(jīng)常有香客問我,道長塞颁,這世上最難降的妖魔是什么浦箱? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮祠锣,結(jié)果婚禮上酷窥,老公的妹妹穿的比我還像新娘。我一直安慰自己伴网,他們只是感情好蓬推,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澡腾,像睡著了一般沸伏。 火紅的嫁衣襯著肌膚如雪募逞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天馋评,我揣著相機(jī)與錄音放接,去河邊找鬼。 笑死留特,一個(gè)胖子當(dāng)著我的面吹牛纠脾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜕青,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼苟蹈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了右核?” 一聲冷哼從身側(cè)響起慧脱,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贺喝,沒想到半個(gè)月后菱鸥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡躏鱼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年氮采,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片染苛。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鹊漠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茶行,到底是詐尸還是另有隱情躯概,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布畔师,位于F島的核電站娶靡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏茉唉。R本人自食惡果不足惜固蛾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望度陆。 院中可真熱鬧艾凯,春花似錦、人聲如沸懂傀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恃泪,卻和暖如春郑兴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贝乎。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國打工情连, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人览效。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓却舀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锤灿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子挽拔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)但校,斷路器螃诅,智...
    卡卡羅2017閱讀 134,600評(píng)論 18 139
  • 22年12月更新:個(gè)人網(wǎng)站關(guān)停,如果仍舊對(duì)舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,160評(píng)論 22 257
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,516評(píng)論 25 707
  • 文/陌客 入夜之后状囱,外面突然就下起了大雨术裸。電閃雷鳴,好不狼狽浪箭。同宿舍的哥們穗椅,急匆匆趕回,一口一個(gè)您奶栖,聽著我一身雞皮...
    畫子歸閱讀 285評(píng)論 0 0
  • 我喜歡的樣子你都有,我們單獨(dú)在一起的時(shí)候或者在網(wǎng)上的時(shí)候無話不談门坷,但就是到了生活中宣鄙,遇到認(rèn)識(shí)的人的時(shí)候就變得慌張不...
    天霸楠閱讀 197評(píng)論 0 0