date: 2017-03-14 21:08:42
Holi需要枝哄。
之前爬的課表街图,現(xiàn)在需要將那些個一連串的字符串分割成想要的單獨的數(shù)據(jù),做個性化推送金吗。
程序的前面和之前一樣十兢,模擬登錄。
在處理選課/改課這個網(wǎng)頁的時候摇庙,還是蠻復(fù)雜的旱物。
遇神殺神,見鬼殺鬼卫袒。
爬蟲
def Store(self):
# 改課選課
grade_page = self.session.get(
"http://yjsxt.xidian.edu.cn/electiveForwardAction.do")
bsObj = BeautifulSoup(grade_page.text, "html.parser")
table = bsObj.findAll("table", {"class": "list_2title"})[0]
rows = table.findAll("tr")
# 刪除特定的標(biāo)簽和其標(biāo)簽下的內(nèi)容
# 方法:
# 去除標(biāo)簽:[s.extract() for s in soup('script')]
[s.extract() for s in bsObj.findAll(
'td', attrs={'class': "special_background textLeft"})]
csvFile = open('./xuankegaike.csv', 'w', newline='', encoding='utf-8')
writer = csv.writer(csvFile)
writer.writerow(('課程編號', '課程名稱', '學(xué)分', '學(xué)位課', '上課學(xué)期',
'任課教師', '校區(qū)', '上課地點/星期/節(jié)次/周次', '分班號'))
csvRow = []
try:
for row in rows:
csvRow = []
# for cell in row.findAll('td')[:-1]:
for cell in row.findAll('td', attrs={'valign': "middle"})[:-1]:
csvRow.append(cell.get_text().strip().replace(' ', ''))
writer.writerow(csvRow)
finally:
csvFile.close()
csvFile1 = open('./xuankegaike.csv', 'r', encoding='utf-8')
reader = csv.DictReader(csvFile1)
正個頁面有一張大table宵呛,但是里面分布的真不整齊。
新方法s.extract():
刪除特定的標(biāo)簽和其標(biāo)簽下的內(nèi)容
方法:
去除標(biāo)簽:[s.extract() for s in soup('script')]
s.extract()方法可以刪除標(biāo)簽或指定標(biāo)簽下的內(nèi)容夕凝。
獲取指定td下的內(nèi)容:
row.findAll('td', attrs={'valign': "middle"})[:-1]:
這幾次爬蟲對于切片還是用的很好的宝穗。
爬回待處理table:
課程編號,課程名稱,學(xué)分,學(xué)位課,上課學(xué)期,任課教師,校區(qū),上課地點/星期/節(jié)次/周次,分班號
G00FL1020,綜合英語,2,是,2016秋,培養(yǎng)辦,北校區(qū),,免修班
G00HA1012,科學(xué)道德與學(xué)風(fēng),0,是,2016秋,梁昌洪,南校區(qū),,不分班
G00HA1010,中國特色社會主義理論與實踐,2,是,2016秋,肖群,北校區(qū),"J-201/星期一/(9-11)2,3,4,5,7,8,9,10,11,12,13",02
G00HA1011,自然辯證法概論,1,是,2017春,朱丹瓊,北校區(qū),"J-205/星期一/(3-4)2,3,4,5,7,8,9,11,12",07
G00FL1023,英語聽說,1,是,2016秋,姜寧,北校區(qū),"西-508/星期二/(7-8)2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18",07
G00FL1026,英美文化,1,是,2017春,鄒甜甜,北校區(qū),"西-514/星期一/(1-2)2,3,4,5,7,8,9,11,12,13,15,16,17,18",01
Z00MS1031,工程優(yōu)化方法及應(yīng)用,3,是,2016秋,寇曉麗,北校區(qū),"J-205/星期四/(9-11)2,4,5,7,8,9,10,11,13,14,15,16,17,18,19",01
Z08EE1011,算法設(shè)計技術(shù)與方法,3,是,2016秋,公茂果,北校區(qū),"J-304/星期三/(9-11)18J-304/星期五/(9-11)2,5,7,8,9,10,11,12,13,14,15,16,17,18,20",不分班
Z08TE1107,寬帶無線通信,3,是,2016秋,盛敏,北校區(qū),"J-204/星期一/(3-4)2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18J-204/星期四/(1-2)2,4,8,10,12,14,16,18",不分班
Z08TE1140,信號檢測與估值理論,3,是,2017春,李穎,北校區(qū),"J-208/星期三/(3-4)2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17J-208/星期五/(1-2)2,4,6,8,10,12,14,16",不分班
G00HA0040,體育,0.5,否,2016秋,白光斌,北校區(qū),"體育館/星期三/(3-4)3,4,5,7,8,9,10,11,12,13",01
G00HA0041,體育,0.5,否,2017春,白光斌,北校區(qū),"體育館/星期三/(5-6)2,3,4,5,6,7,8,9,10,11",02
Z08TE1222,擴頻通信系統(tǒng),2,否,2016秋,劉乃安,北校區(qū),"J-205/星期二/(9-11)4,5,7,8,9,10,11,12,13,14,15",不分班
G00HA1016,知識產(chǎn)權(quán)與專利申請,1,否,2016秋,王喜媛,北校區(qū),"J-101/星期二/(1-2)3,4,5,7,8,9,10,11,12",01
G00GS1001,企業(yè)實習(xí)報告,2,否,2016秋,培養(yǎng)辦,北校區(qū),,不分班
G00GS1002,開題報告,2,否,2016秋,培養(yǎng)辦,北校區(qū),,不分班
G00GS1003,中期檢查,2,否,2016秋,培養(yǎng)辦,北校區(qū),,不分班
Z08TE1212,MIMO系統(tǒng)與OFDM傳輸技術(shù),2,否,2016秋,趙力強,北校區(qū),"J-204/星期二/(5-6)3,4,5,7,8,9,10,11,12J-204/星期四/(5-6)4,5,7,8,9,10,11",不分班
Z08TE1216,圖像工程,3,否,2016秋,盧朝陽,李靜,北校區(qū),"J-208/星期五/(5-8)2,4,5,7,8,9,10,11,12,13,14,15",不分班
Z08EE1238,科學(xué)精神與方法專題講座,2,否,2017春,梁昌洪,北校區(qū),"圖書館報告廳(3樓)/星期四/(9-11)3,4,5,6,7,8,9,10,11,12,13",不分班
前幾項都是可以直接存到MySQL码秉,現(xiàn)在要做的就是把 上課地點/星期/節(jié)次/周次 這一欄切割后存進(jìn)MySQL逮矛。
方法:split()
首先分析爬回的table。
里面的上課地點/星期/節(jié)次/周次可以分為三類:
- 空转砖。比如綜合英語须鼎,科學(xué)道德與學(xué)分。
- 一周只有一節(jié)課的課府蔗。
- 一周有兩節(jié)課的課晋控。
講道理是要按照三種方法來對字符型切割。
但是該怎么來分類姓赤。
我的第一個思路是用:try赡译,except。
但是這幾個并不是用來處理選擇結(jié)構(gòu)的吧模捂。
但是try捶朵,except,else狂男,finally還是很好用的综看。
選擇結(jié)構(gòu)?難道不應(yīng)該是if岖食,else嗎红碑?
對!就是它!
對這幾種不同類型的上課地點/星期/節(jié)次/周次字符串的長度進(jìn)行分析析珊,三類的長度大概如下:
第一類:長度為0羡鸥;
第二類:長度為50~60;
第三類:長度60~90.
這樣一來就按照上課地點/星期/節(jié)次/周次的長度來判斷分割方法忠寻。
# # 使用 execute() 方法執(zhí)行 SQL 查詢
try:
if len(e['上課地點/星期/節(jié)次/周次']) > 60:
cursor.execute(sql, (
e['課程編號'].strip(),
e['課程名稱'].strip(),
e['學(xué)分'].strip(),
e['學(xué)位課'].strip(),
e['上課學(xué)期'].strip(),
e['任課教師'].strip(),
e['校區(qū)'].strip(),
e['上課地點/星期/節(jié)次/周次'].split("/")[0],
e['上課地點/星期/節(jié)次/周次'].split("/")[1],
e['上課地點/星期/節(jié)次/周次'].split(
"(")[1].split(")")[0][0],
e['上課地點/星期/節(jié)次/周次'].split("/")[2][5:-
5].lstrip(')'),
e['分班號'].strip()))
# 存兩次
cursor.execute(sql, (
e['課程編號'].strip(),
e['課程名稱'].strip(),
e['學(xué)分'].strip(),
e['學(xué)位課'].strip(),
e['上課學(xué)期'].strip(),
e['任課教師'].strip(),
e['校區(qū)'].strip(),
e['上課地點/星期/節(jié)次/周次'].split("/")[2][-5:],
e['上課地點/星期/節(jié)次/周次'].split("/")[3],
e['上課地點/星期/節(jié)次/周次'].split("/")[4][1],
e['上課地點/星期/節(jié)次/周次'].split(
"/")[4][5:].lstrip(')'),
e['分班號'].strip()))
else:
cursor.execute(sql, (
e['課程編號'].strip(),
e['課程名稱'].strip(),
e['學(xué)分'].strip(),
e['學(xué)位課'].strip(),
e['上課學(xué)期'].strip(),
e['任課教師'].strip(),
e['校區(qū)'].strip(),
e['上課地點/星期/節(jié)次/周次'].split("/")[0],
e['上課地點/星期/節(jié)次/周次'].split("/")[1],
e['上課地點/星期/節(jié)次/周次'].split(
"(")[1].split(")")[0][0],
e['上課地點/星期/節(jié)次/周次'].split(
"/")[2][5:].lstrip(')'),
e['分班號'].strip()))
except:
# else len(e['上課地點/星期/節(jié)次/周次']) == 0:
cursor.execute(sql, (
e['課程編號'].strip(),
e['課程名稱'].strip(),
e['學(xué)分'].strip(),
e['學(xué)位課'].strip(),
e['上課學(xué)期'].strip(),
e['任課教師'].strip(),
e['校區(qū)'].strip(),
e['上課地點/星期/節(jié)次/周次'],
e['上課地點/星期/節(jié)次/周次'],
e['上課地點/星期/節(jié)次/周次'],
e['上課地點/星期/節(jié)次/周次'],
e['分班號'].strip()))
if
下面包含兩部分:
- 字符串長度大于60的惧浴,即一周有兩節(jié)課的情況。
- 一周有兩節(jié)課的情況奕剃,將該課程在數(shù)據(jù)庫存兩次衷旅,但是兩次的上課時間、地點纵朋、周次是不一樣的柿顶。
else
處理長度小于60的,即一周只要一節(jié)課的課操软。
except
當(dāng)前兩項都出現(xiàn)異常時嘁锯,其必然是第一類情況,字符串為空聂薪,直接存進(jìn)就可以家乘。
split
split的幾種用法:
split("/")[0]
:按照“/”分割,取第一個切片胆建。
split("(")[1].split(")")[0][0]
取“()”內(nèi)的字符串的第一個烤低。
最后
將里面的簡單字符串都處理為數(shù)字。
for e in reader:
# 是否是學(xué)位課
if e['學(xué)位課'] == '是':
e['學(xué)位課'] = '1'
else:
e['學(xué)位課'] = '0'
# 學(xué)期
if e['上課學(xué)期'] == '2016秋':
e['上課學(xué)期'] = '0'
else:
e['上課學(xué)期'] = '1'
存進(jìn)數(shù)據(jù)庫了笆载。
這次還是發(fā)現(xiàn)了很多的問題扑馁。
歸根結(jié)底,還是基礎(chǔ)不太好凉驻,是得花時間在研習(xí)下Python基礎(chǔ)腻要。