Python实现爬虫抓取OJ代码

本文介绍了一个用于爬取HDOJ上用户AC代码的Python爬虫程序。该程序能够登录HDOJ并获取用户的AC代码,保存为本地文件。代码中包括登录功能及代码解析部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用python初步写了个爬虫, 这个爬虫用来爬取 某个用户在HDOJ上面某一页代码,前提是你注册了HDOJ, 并且正确的输入了用户名跟密码, 目前只能根据url写死某一页, 后期会考虑多种可能性。
调试了很久, 在去掉多余字符的方法上显得有些笨拙, 而且对python编码方式, 以及字符串的方法使用还不熟练, 应该会有加强版代码。
有个问题, 在登录的环节, 我是在浏览器中check的view Source, 发现提交到服务器的信息中, Sign In, 与 Sign in两种写法都行, 我YY不到他的后端是怎么实现的。

同时我在HDOJ首页登录是失败的, 而在登录页是成功的, 很奇怪。。。



Source Code: (Python的代码风格需要提高啊, sad.....)

#这是 改进版的代码, By geek7 2014-07-27 11:48, 可以爬取我在HDOJ的所有AC代码, 唯一的小的瑕疵在于: 如果题号相同的AC代码, 我爬了最后一次AC的。。
import urllib
import http.cookiejar
import re;
#import time
user = ""

def login(): # 登陆函数
  print('请输入你的账号')
  global user
  user = input()
  print('请输入你的密码')
  password = input()
  
  # 设置一个cookie处理器,它负责从服务器下载cookie到本地,并且在发送请求时带上本地的cookie
  cj = http.cookiejar.LWPCookieJar()  
  cookie_support = urllib.request.HTTPCookieProcessor(cj)  
  opener = urllib.request.build_opener(cookie_support, urllib.request.HTTPHandler)  
  urllib.request.install_opener(opener)  
  
  url = 'http://acm.hdu.edu.cn/userloginex.php?action=login' # 登陆的界面
  
  # 这个最好加上,不然由于内部信息默认显示为机器代理,可能被服务器403 Forbidden拒绝访问
  header={'User-Agent':'Magic Browser'}
  
  # 构造Post数据,从抓大的包里分析得出的或者通过查看网页源代码可以得到  
  data = {
      'username' : user, # 你的用户名
      'userpass' : password, # 你的密码,密码可能是明文传输也可能是密文,如果是密文需要调用相应的加密算法加密
      'login' : 'Sign In'  # 特有数据,不同网站可能不同
  }

#  print(user, password);
 # print(data); 
#  print(data['username'], data['userpass'], data['login']);
  data = urllib.parse.urlencode(data).encode('utf-8')
  
  # 发送请求,得到服务器给我们的响应
  response = urllib.request.Request(url, data, header)
  # 通过urllib提供的request方法来向指定Url发送我们构造的数据,并完成登录过程
  r = urllib.request.urlopen(response)

  html = r.read();
 # print(html);

  fout = open('login.html', 'wb');
  fout.write(html);
  fout.close();
  
  return

  
def solve(html, i, postion):
  txt = html.decode('gbk','ignore')

  src = txt.find('#include');
  main = txt.find("main");
  end = txt.find("return 0", main); 
  end += 12;

  ans = txt[src:end];
 
  ans = ans.replace('<', '<');
  ans = ans.replace('>', '>');
  ans = ans.replace('"', '"');
  ans = ans.replace('&', '&');

  #print(ans);
  fout = open('Pro' + str(i) + '.cpp', 'w')

  postion += '\n';
  fout.write(postion);
  fout.write(ans);
  fout.close()
  return

def run(userName, url, isFirst): # 抓取所有AC代码
    if isFirst == 1:
      url = 'http://acm.hdu.edu.cn/status.php?user=' + userName + '&lang=&status=5'; #AC URL

    print(url);
    response = urllib.request.urlopen(url)
    html = response.read();
    
    txt = html.decode('gbk','ignore')
  #  print(txt);
    codePos = "viewcode";
    proPos = "showproblem";
    codeId = [m.end() for m in re.finditer(codePos, txt)];
    pp = [n.end() for n in re.finditer(proPos, txt)];
    #debuge
   # print(codeId);
    #print(pp)

    cnt = 0;
    for k in codeId:
      j = k + 9;
      s = 0;
      pos = int(pp[cnt]) + 9;
      cnt += 1;
      _x = int(txt[pos:pos+4]);#Problem 编号
      
      while txt[j] != "\"": #Get CODE 在web中页面的传值参数
        s = s*10 + int(txt[j]);
        j = j + 1;

      codeUrl = "http://acm.hdu.edu.cn/viewcode.php?rid=" + str(s);
    #  print(codeUrl);
      res = urllib.request.urlopen(codeUrl)
      htm = res.read();
      solve(htm, _x, codeUrl);

      print("ok");

    print(txt);
    nexPos = txt.find("Next Page");
    print(nexPos);
    if nexPos != -1:
      p = nexPos;
      while True:
        if txt[p:p+4] == 'href':
          begPos = p;
          break;
        p -= 1;

      nextPageUrl = 'http://acm.hdu.edu.cn' + txt[begPos+6: nexPos-2];
      print(nextPageUrl);
      run(userName, nextPageUrl, 0);
    return

if __name__ == '__main__':
  login()
  run(user, "", 1);
  input();#read key


最后我运行这段代码成功抓取了我所有AC的code。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值