python爬虫自动提交HDU并获取AC状态(p3+request+Beatifulsoup)

说明

今天下午搞了好一会儿,源于上周日的沈阳网络赛,竟然可以枚举答案交1024发……想到如果自己能写个爬虫自动提交那该多好啊,源于这总冲动自己今天花了一个下午实现了这个小玩意儿.

效果图

这里写图片描述

实现过程

其实主要是3个步骤:

  • login 登录
  • submit 提交代码
  • report status 范围状态(AC没有?)

首先是登录,就是要把你的id 和 密码post 到HDU ,我们可以打开HDU 的主页然后分析提交页面(Chrome +F12)
可以看到这几个东西
这里写图片描述
这就是我们需要添加到post data上的东西.
与用requests 创建一个会话然后,post data 上去就行了
这就是login

submit

这个也是一个post动作,具体和上一步是一样的.先去分析网页.

status

这个比较简单,只需要向对应网页发送请求就行了.,
python爬虫自动提交HDU并获取AC状态(p3+request+Beatifulsoup)_第1张图片
然后我分析了一下源码. 发现他的上图的数据存在一个叫做 fix_table的表里,用Beatifulsoup 解析一下就好了.

code


import sys
import requests
import time
from bs4 import BeautifulSoup


class HDUSubmit(object):

    log_url = 'http://acm.hdu.edu.cn/userloginex.php?action=login'
    submit_url = 'http://acm.hdu.edu.cn/submit.php?action=submit'
    status_url = 'http://acm.hdu.edu.cn/status.php?'
    language_map = {
        "Java": 5,
        "Cpp": 0
    }

    def __init__(self, user_id, password):

        self.id = user_id
        self.password = password
        self.session = requests.session()
        self.session.headers.update({
            "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36\
             (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
        })
        self.cookie_jar = requests.cookies.RequestsCookieJar()

    def login(self):
        params = {
            "username": self.id,
            "userpass": self.password,
            "login": "Sign In"
        }
        r = self.session.request('POST', self.log_url, data=params, cookies=self.cookie_jar)
        print('log status_code:', r.status_code)
        return r

    def submit(self, pid, code, language='Cpp'):
        params = {
            'check': 0,
            'problemid': pid,
            'language': self.language_map[language],
            'usercode': code
        }
        r = self.session.request('POST', self.submit_url, data=params, cookies=self.cookie_jar)
        print("submit status_code", r.status_code)

        if r.status_code == 200:
            print('submit success')
            time.sleep(10)

            # 处理状态查询

            return self.status(pid)

        else:
            print('submit failed')
        return r

    def status(self, pid):
        params = {
            'pid': pid,
            'user': self.id
        }
        r = self.session.get(self.status_url, params=params)
        soup = BeautifulSoup(r.text, 'lxml')
        trs = soup.find('div', {'id': 'fixed_table'})('tr')
        model = [td.string for td in trs[0]('td')]
        data = [td.string for td in trs[1]('td')]
        pat = ['{:^%d}' % (max(len(model[i]), len(data[i]))) for i in range(len(data))]
        for i in range(len(model)):
            print(pat[i].format(model[i]), end=' ')
        print()
        for i in range(len(data)):
            print(pat[i].format(data[i]), end=' ')
        return r


def read_code(filename):
    code = None

    with open(filename) as f:
        code = f.read()
    return code


def main(lan='Cpp', argv=None):

    if argv is None:
        try:
            argv = sys.argv[1:]
        except:
            print("请输入id和密码:")
            argv =[]
            argv.append(input("id:"))
            argv.append(input("password:"))
            argv.append(input("代码文件名:"))
            argv.append(input("题号:"))
    code = read_code(argv[2])
    hdu = HDUSubmit(argv[0], argv[1])
    hdu.login()
    hdu.submit(argv[3], code,lan)


if __name__ == '__main__':
    main()


你可能感兴趣的:(python,爬虫,HDU登录,python)