Python 之 BNUOJ代码抓取器

 

经过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的符号属性,转化成一般的。如,空格,&nbsp;,等等。

最后因为保存在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()


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值