分析一下他們的代碼,我在瀏覽器中對應位置右鍵,而後點擊檢查元素,能夠找到對應部分的代碼。可是,直接查看當前網頁的源碼發現,裏面並無對應的代碼。我猜想這裏是根據服務器上的數據動態生成的這部分代碼,因此咱們須要找到數據文件,以便向服務器申請,獲得這部分資源。css
在剛纔查看元素的地方接着找數據文件,在Network裏面的文件中很順利的就找到了,並在報文中拿到了URL和請求方法。html
查看一下這個文件發現是JSON文件,那樣的話難度就又下降了,由於Python中有json庫,解析json的能力很強。能夠直接將json轉換爲字典和列表類型。web
在這裏我簡單介紹一下數據解析的過程吧。首先,我將爬取到的json文本轉換成某種數據類型,具體由數據決定,通常不是字典就是列表。查看類型發現是字典,且字典中有三個key值,而咱們須要的key在一個叫data的key中。json
而data中的數據是一個學生信息的列表類型,列表的每一個元素都是一個字典,包括學生姓名,學號等信息。能夠利用下標獲取列表元素,並用key值獲得你想拿到的信息。好比,利用Url獲得網頁連接。瀏覽器
這時候咱們爬取須要的信息的準備工做能夠說是結束了,咱們拿到了數據的URL,而且知道了數據類型和數據結構。因而,咱們只須要用requests庫爬一下這個頁面,而後用json解析一下,而且篩選有用的信息就行了。服務器
(沒用到BeautifulSoup和re庫有點小失落)網絡
接下來就是建立文件,就沒有什麼難度了。只是在爲每一個學生建立文件的時候注意一下,建立好之後及時的回到上層目錄,不然,可能會讓文件一層層的嵌套下去。數據結構
# -*- coding:utf-8 -*- import requests import json import os #抓取頁面 url = 'https://edu.cnblogs.com/Homework/GetAnswers?homeworkId=2420&_=1542959851766' try: r = requests.get(url,timeout=20) r.raise_for_status() r.encoding = r.apparent_encoding except: print('網絡異常或頁面未找到,請重試') #利用json拿到數據列表,每一個列表元素都是字典 datas = json.loads(r.text)['data'] result = "" #數據處理 for data in datas: result += str(data['StudentNo'])+','+data['RealName']+','+data['DateAdded'].replace('T',' ')+','+data['Title']+','+data['Url']+'\n' #寫入文件 with open('hwlist.csv','w') as f: f.write(result) #建立文件夾hwFolder os.mkdir('hwFolder') os.chdir('hwFolder') #建立每一個學生的做業文件 for data in datas: #建立目錄 os.mkdir(str(data['StudentNo'])) os.chdir(str(data['StudentNo'])) #抓取頁面 try: webmsg = requests.get(data['Url'],timeout=20) webmsg.raise_for_status() webmsg.encoding = webmsg.apparent_encoding except: print('網絡異常或頁面未找到,請重試') #保存抓到的頁面 with open(str(data['StudentNo'])+'.html','wb') as f: f.write(webmsg.content) os.chdir(os.path.pardir)
上圖是hwlist.csv文件的部分結果(Excel下打開)app
像以前那樣爬取頁面的話,實際上是有點問題的。首先,咱們只是爬取了頁面的內容,可是並無抓取到頁面的樣式,頁面顯示會不太正常,排版混亂。其次,頁面中還有圖片等元素都不會顯示出來。並且,若是遇到網絡問題代碼須要再次運行的時候還會遇到一個問題,那就是目錄已經存在了,咱們在建立目錄就會失敗。除此以外仍是有很多問題的,此處我先解決以前說到的幾個問題。即顯示問題和目錄問題。編輯器
如何解決我提到的這些問題呢,目錄問題我使用了一種比較容易實現的方案,那就是先判斷當前目錄是否存在,若是不存在就建立目錄,不然就什麼都不作。至於文件,暫定的方法是直接覆蓋。顯示問題也比較好解決,抓取網頁和抓取樣式或者網頁其實都同樣,就是用URL發送一個請求,來得到這個資源,其實和抓取HTML相比,就是文件格式不太一致。
以抓取樣式表(CSS)爲例,樣式的URL怎麼獲取呢?有一些樣式是在一個叫作Link的標籤的href屬性裏,這裏面就是外聯樣式存儲的位置。把它提取出來,請求這個樣式,而且修改原來的href屬性爲抓到的文件在本身電腦上的保存位置便可。這樣的話便可保證抓到的CSS能夠正常使用,確保排版正確。
固然了,即便這樣,和本來的網頁也是有差異的,由於抓取到的資源仍是不夠,和瀏覽器中得到的元素對比一下就會發現還差很多。鑑於本人能力有限,這裏就補充一下爬取外聯CSS和圖片的內容,感興趣的能夠看一看。
Tips:這裏解析HTML頁面藉助了強大的BeautifulSoup4庫(解析標籤和玩同樣)和re庫,使工做量減小了很多。(安裝bs4庫: pip install BeautifulSoup4)
# -*- coding:utf-8 -*- import requests import json import os import re from bs4 import BeautifulSoup def getHtml(url,timeout=110): try: res = requests.get(url,timeout) res.raise_for_status() res.encoding = res.apparent_encoding return res except: print('網絡異常,'+url+"爬取失敗") def saveFile(name,content,mode='w'): try: with open(name,mode) as f: f.write(content) except: print("文件"+name+"建立失敗") def getSource(text): #抓取樣式 root_url = 'https://www.cnblogs.com' soup = BeautifulSoup(text,'html.parser') for i in soup('link'): css_list = [css for css in i['href'].split('/') if 'css' in css] if css_list!=[]: filename = re.search(r'.*css',css_list[0]).group(0) r = requests.get(root_url+i['href']) saveFile(filename,r.content,'wb') text = text.replace(i['href'],'Source/'+filename) #抓取圖片 用戶本身插入的圖片和網站本身生成的圖片都抓 #用戶本身插的那些格式很亂……用戶本身搞的東西就是個坑 for i in soup('img'): try: img_list = [img for img in i['src'].split('/') if 'gif' in img or 'png' in img or 'jpeg' in img] except KeyError :#某用戶本身改了HTML代碼 得讓我單獨判斷一下 img_list = [] if img_list!=[]: filename = img_list[0] try: r = requests.get(root_url+i['src']) r.raise_for_status() except: if not 'http' in i['src']: r = requests.get("https:"+i['src']) else:#又是某用戶寫博客用了HTML編輯器,寫的還不對 r = requests.get(i['src']) saveFile(filename,r.content,'wb') text = text.replace(i['src'],'Source/'+filename) #text用於修改原始的頁面連接,保證本地能夠正常查看頁面 return text #############################主程序############################ #抓取頁面 並獲得數據 r = getHtml('https://edu.cnblogs.com/Homework/GetAnswers?homeworkId=2420&_=1542959851766') datas = json.loads(r.text)['data'] #處理數據並將數據寫入文件 result = "" for data in datas: result += str(data['StudentNo'])+','+data['RealName']+','+data['DateAdded'].replace('T',' ')+','+data['Title']+','+data['Url']+'\n' saveFile('hwlist.csv',result,'w') #建立文件夾hwFolder if not os.path.exists('hwFolder'): os.mkdir('hwFolder') os.chdir('hwFolder') #建立每一個學生的做業文件 for data in datas: #建立目錄 if not os.path.exists(str(data['StudentNo'])): os.mkdir(str(data['StudentNo'])) os.chdir(str(data['StudentNo'])) #抓取頁面 webmsg = requests.get(data['Url']) print('當前的URL:'+data['Url'])#等待的過程有字出來不會無聊 #頁面的一些資源 if not os.path.exists('Source'): os.mkdir('Source') os.chdir('Source') webtext = getSource(webmsg.text) os.chdir(os.path.pardir) saveFile(str(data['StudentNo'])+'.html',webtext.encode(),'wb') os.chdir(os.path.pardir)
若是你的網絡沒問題,講道理,應該不會拋異常。接下來找個頁面看看效果吧:
排版抓出來了,挺炫的,固然,圖片也抓了。
考慮到有人會HTML,我把被程序調整後的HTML代碼找一個給你們看看,箭頭指向的地方都是程序本身改過的地方:
其實,雖然如今又和原頁面接近了很多,可是……我暫時沒有時間繼續完善了,之後還會繼續完善。給你們一個原博客的圖片,你會我先我仍是少了些東西。暫時先這樣吧。