[Python]南郵OJ代碼備份爬蟲

來源:互聯網
上載者:User

標籤:style   封裝   raw_input   word   學習   字元   name   pytho   regular   

之前看過Python學習的經驗,說以project為導向學習。

自己分析了一下,一般接觸Python的都有一定的其它語言基礎,對於程式設計的基本邏輯,文法都有一個大概的瞭解。而Python這樣的指令碼語言。沒有過於獨特的文法,在一定的其它語言的基礎上。更是能夠直接上手的。

之前看Python簡明教程,半天沒有進度。正好遇上Python爬蟲項目,直接上手,方便快捷。

網站:http://acm.njupt.edu.cn/welcome.do?

method=index,正值系統更新,於是寫一個備份代碼的爬蟲。

使用的Python庫

urllib庫:

這個庫封裝了通過URL與網路server通訊的方法。包括HTTP的request,response等等。眼下為止基本夠用。

re庫:

即regularexpress,正則表達式庫。用來在HTML文檔中檢索資訊。

基本架構

首先通過HTTP協議,向目標server提交request請求,然後接受response應答。

我們再從應答中,得到我們須要的內容:使用者cookie和代碼。最後建立本地檔案,把他們放進去就可以。

詳細步驟A.HTTP請求

Python果然是短平快的語言,例如以下三行搞定:

myUrl ="http://acm.njupt.edu.cn/acmhome/index"#目標頁面req=urllib2.Request(myUrl)#用URL得到request對象myResponse = urllib2.urlopen(req)#通過urlopen()函數發送request,得到返回的responsemyPage = myResponse.read()#在response中讀取頁面資訊

B.登入許可權擷取

分析頁面我們看到,要備份代碼須要提交username與password。並且提交的頁面不是首頁,而是登陸頁。依據HTTP的知識,須要用POST方法提交包括表單資訊的request。使用chrome開發人員工具,檢測到提價的表達包括例如以下內容。



這在Python中也好實現:

myUrl ="http://acm.njupt.edu.cn/acmhome/login.do"#url地址改為登入頁self.postdata = urllib.urlencode({           ‘userName‘:self.userName,           ‘password‘:self.passWord})#{}中為Python的字典結構資料,傳入username和password#urlencode()函數把字典結構編碼為特定的data類req=urllib2.Request(           url = myUrl,           data = self.postdata           )#給Request傳入URL以及編碼好的data資料myResponse = urllib2.urlopen(req)myPage = myResponse.read()

C.處理cookie

之前的還少考慮了一個東西。就是登入後要訪問網站的其它頁面時。須要用到登入的cookie。

Python中沒有特殊定義的訪問貌似是不保留cookie的。於是我們要從寫一個可保留cookie的HTTP通訊方式。

首先是Python中的幾個概念:

opener:用於通訊的對象,之前代碼中urllib.urlopen()使用系統預設的opener,等價於default_opener.urlopen()

handler:一個opener包括多個hander。用於處理通訊間的各種子問題,包括cookie問題。

於是,上面處理cookie的方法就是。重寫一個opener,給予其可處理cookie的handler。

cookie_support =urllib2.HTTPCookieProcessor(cookielib.CookieJar())#建立cookie_handleropener =urllib2.build_opener(cookie_support,urllib2.HTTPHandler)#用cookie_handler建立cookie_openerurllib2.install_opener(opener)#設定為預設opener

到此,我們能夠實現登入許可權擷取。

D.定位到字碼頁面

我們要從首頁開始,找到字碼頁面。本來直接擷取URL就可以。

只是發現字碼頁面URL例如以下:

這個頁麵包括了時間和登入資訊的未知編碼。應該是通過轉義的。這裡的解決方案是通過已知頁面擷取URL而不是手動輸入。

分析頁面後。能夠例如以下獲得字碼頁面:

首頁-->使用者資訊-->通過代碼-->’G++|GCC|JAVA’欄位超連結,例如以下

於是,解析獲得的HTML,得到超連結:

myItem = re.findall(‘<ahref=\"/acmhome/solutionCode\.do\?id\=.*?\"\ ‘,myPage,re.S)for item in myItem:url=‘http://acm.njupt.edu.cn/acmhome/solutionCode.do?

id=‘+item[37:len(item)-2]

E.扣去文本


如上。能夠看出網站是用XML來儲存,轉義為HTML。於是我們要替換文本中的轉義標籤。得到正常文本:

class Tool:    A= re.compile("?\;")    B= re.compile("\<BR\>")    C= re.compile("<\;")    D= re.compile(">\;")    E= re.compile(""\;")    F= re.compile("&")    G= re.compile("Times\ New\ Roman\"\>")    H= re.compile("\</font\>")    I= re.compile("‘")    J= re.compile("語言:(.*)?face=\"",re.DOTALL)   def replace_char(self,x):       x=self.A.sub(" ",x)       x=self.B.sub("\r",x)       x=self.C.sub("<",x)       x=self.D.sub(">",x)       x=self.E.sub("\"",x)       x=self.F.sub("&",x)       x=self.G.sub("",x)       x=self.H.sub("",x)       x=self.I.sub("\‘",x)       x=self.J.sub("",x)       return x

*注意,Python中字串有替換函數,str.replace(替換字元,原字元)。只是假設要依據正則表達式來替換。須要用re模組的re.sub()函數才行。replace不能使用正則表達式。

*還有。replace返回替換的字串,原始字串沒有不論什麼改變

F.存入檔案

首先要得到代碼的中文題目作為檔案名稱。只是這在自己的字碼頁看不到,僅僅能到代碼首頁去找。找到後抓取<title>中的欄位作為使用者名稱就可以。

tname=re.findall(‘title\>.*?\</title‘,p,re.S)f =open(tname[0][6:len(tname[0])-7]+‘_‘+sname[8:len(sname)-8]+‘.txt‘,‘w+‘)f.write(self.mytool.replace_char(mytem[0]))f.close()
終於程式

# -*- coding: cp936 -*-#copyright by B08020129 import urllib2import urllibimport reimport threadimport timeimport cookielib cookie_support =urllib2.HTTPCookieProcessor(cookielib.CookieJar())opener = urllib2.build_opener(cookie_support,urllib2.HTTPHandler)urllib2.install_opener(opener)  class Tool:    A= re.compile("?\;")    B= re.compile("\<BR\>")    C= re.compile("<\;")    D= re.compile(">\;")    E = re.compile(""\;")    F = re.compile("&")    G =re.compile("Times\ New\ Roman\"\>")    H= re.compile("\</font\>")    I= re.compile("‘")    J= re.compile("語言:(.*)?face=\"",re.DOTALL)   def replace_char(self,x):       x=self.A.sub(" ",x)       x=self.B.sub("\r",x)        x=self.C.sub("<",x)       x=self.D.sub(">",x)       x=self.E.sub("\"",x)       x=self.F.sub("&",x)       x=self.G.sub("",x)       x=self.H.sub("",x)       x=self.I.sub("\‘",x)       x=self.J.sub("",x)       return x class HTML_Model:    def __init__(self,u,p):        self.userName = u        self.passWord =p       self.mytool = Tool()       self.page = 1       self.postdata = urllib.urlencode({           ‘userName‘:self.userName,           ‘password‘:self.passWord})    def GetPage(self):       myUrl = "http://acm.njupt.edu.cn/acmhome/login.do"       req=urllib2.Request(           url = myUrl,           data = self.postdata           )       myResponse = urllib2.urlopen(req)       myPage = myResponse.read()       flag = True       while flag:           myUrl="http://acm.njupt.edu.cn/acmhome/showstatus.do?

problemId=null&contestId=null&userName="+self.userName+"&result=1&language=&page="+str(self.page) #print(myUrl) myResponse = urllib2.urlopen(myUrl) myPage = myResponse.read() st="\<a\ href\=.*?G\+\+" next = re.search(st,myPage) if next: flag = True else: flag = False myItem = re.findall(‘<ahref=\"/acmhome/solutionCode\.do\?id\=.*?\"\ ‘,myPage,re.S) for item in myItem: #print(item) url=‘http://acm.njupt.edu.cn/acmhome/solutionCode.do?id=‘+item[37:len(item)-2] #print(url) myResponse =urllib2.urlopen(url) myPage = myResponse.read() mytem = re.findall(‘語言.*?

</font>.*?Times NewRoman\"\>.*?\</font\>‘,myPage,re.S) #print(mytem) sName = re.findall(‘源碼--.*?</strong‘,myPage,re.S) for sname in sName: #print(sname[2:len(sname)-8]) name="http://acm.njupt.edu.cn/acmhome/problemdetail.do?&method=showdetail&id="+sname[8:len(sname)-8]; #print(name) p=urllib2.urlopen(name).read() #print(p) tname=re.findall(‘title\>.*?\</title‘,p,re.S) print(tname[0][6:len(tname[0])-7]+‘_‘+sname[8:len(sname)-8]) f =open(tname[0][6:len(tname[0])-7]+‘_‘+sname[8:len(sname)-8]+‘.txt‘,‘w+‘) f.write(self.mytool.replace_char(mytem[0])) f.close() print(‘done!‘) self.page = self.page+1 print u‘plz input the name‘u=raw_input()print u‘plz input password‘p=raw_input()myModel =HTML_Model(u,p)myModel.GetPage()

得到檔案


以及檔案裡的正常代碼:


下一步用更好地方法試著一鍵注冊及提交全部代碼。


[Python]南郵OJ代碼備份爬蟲

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.