经过Wireshark抓包,我发现要抓取BNU上提交过的代码,访问http://www.bnuoj.com/bnuoj/get_source.php?runid=%d&randomid=0.19548853184096515这个链接,其中runid=%d,%d填代码执行的id号。那个randomid不知道是干嘛的。。
然后这个页面就会返回包含代码信息的html页面。
如图:
用python urllib2模块中的opener,打开就能够得到这个页面的html源文件。
url="http://www.bnuoj.com/bnuoj/get_source.php?runid=%d&randomid=0.19548853184096515" % int(runid)
res=opener.open(url)
当然,在抓取源文件时,需要事先登录拿到cookie。
cj=cookielib.CookieJar()
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener.addheaders=defaultHeaders
while True:
username=raw_input(u'Please input your username:')
password=getpass.getpass('Please input your password:')
logindata={'username' : username,
'password' : password,
'cksave' : '365'}
data=urllib.urlencode(logindata)
tmp=opener.open(loginURL,data)
if tmp.read() == 'Yes':
print u'Login successed!'
break
else:
print u'Login failed!'
拿到html代码,格式比较正规。可以从页面中提取到很多有用的信息。比如,用户名,代码语言,etc。
如:
<div style='clear:both;margin:auto;font-weight:bold;text-align:center'>Result: Accepted Memory Used: 1396 KB Time Used: 4 ms </div>
<div style='clear:both;margin:auto;font-weight:bold;text-align:center'>Language: GNU C++ User Name: sssogs Problem ID: 1082 <div>
<div style="clear:both;margin:auto;text-align:center">Share Code? <input name="tisshare" type="radio" style="width:16px" value="1" checked="checked" />Yes <input name="tisshare" value="0" type="radio" style="width:16px" />No</div><div style='clear:both;margin:auto;color:blue;font-weight:bold;text-align:center' id='sharenote'><b>This code is shared.</b></div>
<div style='clear:both;text-align:left'><pre id='source_code' class='cpp'>#include <iostream>
using namespace std;
int main()
{
cout<<13<<endl;
return 0;
}</pre></div>
看上去,有点乱,这时就用强大的正则表达式来处理一下。
现在,我把源代码都提取到了s中。
先除去所有的html标签。
s=re.sub('<.+>','',s)
把html的符号属性,转化成一般的。如,空格, ,等等。
最后因为保存在s中的换行符是''\r\n"的,所以需要把它转化为"\n",这样在文本中的代码才能正常地显示。
s=re.sub('\r\n','\n',s)
保存文件信息
fa=open('BNUOJ_%s.%s'%(info['Problem ID'],extLang[info['Language']]),"w")
print 'BNUOJ_%s.%s'%(info['Problem ID'],extLang[info['Language']])
fa.write('/**\n * Result : %s\n' % info['Result'])
fa.write(' * Language : %s\n' % info['Language'])
fa.write(' * Author Name : %s\n' % info['User Name'])
fa.write(' * Problem ID : %s\n' % info['Problem ID'])
fa.write(' * Time Used : %s\n' % info['Time Used'])
fa.write(' * Memory Used : %s\n' % info['Memory Used'])
fa.write(' */\n')
fa.write(s)
fa.close()
效果图:
附上全部代码:
import re
import httplib
import httplib
import urllib2
import urllib
import cookielib
import getpass
loginURL = 'http://www.bnuoj.com/bnuoj/login.php'
submitURL = 'http://www.bnuoj.com/bnuoj/action.php'
defaultHeaders=[('User-agent','Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)')]
extLang={'GNU C++':'cpp',
'Visual C++':'cpp',
'Visual C':'c',
'GNU C':'c',
'Oracle Java':'java',
'C#':'cs'
}
info={}
def SourceProcess(s,uid,res='Accepted'):
t1=re.search('Permission denined',s)
if t1 != None:
return 0
t1=re.search('(Time Used:\s)(\w+\s?\w+)',s)
info['Time Used']=t1.group(2)
t1=re.search('(Memory Used:\s)(\w+\s?\w+)',s)
info['Memory Used']=t1.group(2)
t1=re.search('(Language:\s)([\w+]+\s?[#\w+]+)',s)
info['Language']=t1.group(2)
t1=re.search('(User Name:\s)([\w+]+\s?[\w+]+)',s)
info['User Name']=t1.group(2)
if info['User Name'] != uid:
return 0
t1=re.search('(Problem ID:\s)([\w+]+\s?[\w+]+)',s)
info['Problem ID']=t1.group(2)
t1=re.search('(Result:\s)([\w+]+\s?[\w+]+)',s)
info['Result']=t1.group(2)
if info['Result'] != res:
return 0
s=re.sub('<.+>','',s)
s=re.sub('( )+','!',s)
s=re.sub('(<)','<',s)
s=re.sub('(>)','>',s)
s=re.sub('(&)','&',s)
s=re.sub('(")','"',s)
s=re.sub('^[ \t\n]*\n','',s)
s=re.sub('\r\n','\n',s)
fa=open('BNUOJ_%s.%s'%(info['Problem ID'],extLang[info['Language']]),"w")
print 'BNUOJ_%s.%s'%(info['Problem ID'],extLang[info['Language']])
fa.write('/**\n * Result : %s\n' % info['Result'])
fa.write(' * Language : %s\n' % info['Language'])
fa.write(' * Author Name : %s\n' % info['User Name'])
fa.write(' * Problem ID : %s\n' % info['Problem ID'])
fa.write(' * Time Used : %s\n' % info['Time Used'])
fa.write(' * Memory Used : %s\n' % info['Memory Used'])
fa.write(' */\n')
fa.write(s)
fa.close()
return 1
def main():
cj=cookielib.CookieJar()
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener.addheaders=defaultHeaders
while True:
username=raw_input(u'Please input your username:')
password=getpass.getpass('Please input your password:')
logindata={'username' : username,
'password' : password,
'cksave' : '365'}
data=urllib.urlencode(logindata)
tmp=opener.open(loginURL,data)
if tmp.read() == 'Yes':
print u'Login successed!'
break
else:
print u'Login failed!'
runid=202669
cnt=0;
while True:
url="http://www.bnuoj.com/bnuoj/get_source.php?runid=%d&randomid=0.19548853184096515" % int(runid)
res=opener.open(url)
if SourceProcess(res.read(),username,'Accepted')==1:
cnt+=1
print cnt
runid=runid-1
print runid
main()