[python]南邮OJ代码备份爬虫

之前看过Python学习的经验,说以工程为导向学习。

自己分析了一下,一般接触Python的都有一定的其他语言基础,对于程序设计的基本逻辑,语法都有一个大概的了解。而Python这种脚本语言,没有过于独特的语法,在一定的其他语言的基础上,更是可以直接上手的。

之前看Python简明教程,半天没有进度。正好遇上Python爬虫项目,直接上手,方便快捷。

网站:http://acm.njupt.edu.cn/welcome.do?method=index,正值系统更新,于是写一个备份代码的爬虫。

使用的Python库

urllib库:

这个库封装了通过URL与网络服务器通信的方法,包括HTTP的request,response等等,目前为止基本够用。

re库:

即regularexpress,正则表达式库。用来在HTML文档中检索信息。

基本框架

首先通过HTTP协议,向目标服务器提交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,得到返回的response
myPage = myResponse.read()#在response中读取页面信息

B.登入权限获取

分析页面我们看到,要备份代码需要提交用户名和密码,而且提交的页面不是主页,而是登陆页。根据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_handler
opener =urllib2.build_opener(cookie_support,urllib2.HTTPHandler)
#用cookie_handler建立cookie_opener
urllib2.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

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 urllib2
import urllib
import re
import thread
import time
import 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代码备份爬虫

时间: 2024-12-29 19:35:02

[python]南邮OJ代码备份爬虫的相关文章

南邮OJ 1005 多项式加法

题目描述:线性表是一种最简单.最基本,也是最常用的数据结构,其用途十分广泛,例如,用带表头结点的单链表求解一元整系数多项式加法和乘法运算.现给两个一元整系数多项式,请求解两者之和. 题目链接:点击打开链接 代码是借鉴别人的,链接:点击打开链接 <span style="font-size:18px;">#include <iostream> using namespace std; class nodeList; class Node //单链表节点 { pri

南邮OJ 1005 多项式加法(二)

一.首先,这个多项式是一个链表,多项式的每一项是链表一个节点,那么可以想到两种情况: 1)多项式只有一项或者是多项式的最后一项,那么这个节点就只需要有系数和指数两个元素,且不需要指向下 一个节点. 2)多项式的其中一项,那么这个节点就需要有系数.指数以及指向下一个节点的指针. <span style="font-size:18px;"><span style="font-size:18px;">class Node { private: in

python写的简单有效的爬虫代码

python写的简单有效的爬虫代码 by 伍雪颖 import re import urllib def getHtml(url): html = urllib.urlopen(url) scode = html.read() return scode def getImage(source): reg = r'src="(.*?\.jpg)"' imgre = re.compile(reg) images = re.findall(imgre,source) x = 0 for i

南邮CTF - Writeup

南邮CTF攻防平台Writeup By:Mirror王宇阳 个人QQ欢迎交流:2821319009 技术水平有限~大佬勿喷 ^_^ Web题 签到题: 直接一梭哈-- md5 collision: 题目源码提示: $md51 = md5('QNKCDZO'); $a = @$_GET['a']; $md52 = @md5($a); if(isset($a)){ if ($a != 'QNKCDZO' && $md51 == $md52) { echo "nctf{********

python学习(二)百度爬虫0.1

参照着网上的爬虫案例(点我),先做了一个demo,基本的爬虫项目创建,以及数据抽取,数据分析,数据保存等等过程基本上有所掌握. 我的需求是需要检索指定的百度贴吧,根据指定的关键字库,搜索出含有关键字的链接,并抽取出来,用于后续告警. 因此,基于需求,分如下步骤: 第一:基于Scrapy创建爬虫项目: 第二:新建TieBaSpider爬虫: 第三:新建外部关键字库dictionary.txt文件,贴吧地址配置url.txt文件: 第一步参考晚上案例. 从第二步开始,编写爬虫,同时创建实例对象以及创

南邮JAVA程序设计实验4 线程程序设计(指针式时钟)

南邮JAVA程序设计实验4  线程程序设计(指针式时钟) 实验目的: 本实验旨在通过实验,培养学生将JAVA 线程的相关知识点(包括线程调度,线程同步等)有机结合并加以综合应用,在实验中设计多线程程序的能力. 实验内容: 设计和编写一个编写一个指针式时钟程序,应用线程实现时钟的走动. 实验设计: 主要是控制时针分针秒针的转动度数,这个直接通过坐标的三角函数值求得,线程方面,隔一秒休眠一下,然后通过时分秒的换算关系来改变三个对应指示针在时钟上的位置 实验代码: import java.awt.*;

python机器登陆新浪微博代码示例

前段时间开始学习Python,一直想不到有什么好的小项目可以做,憋得慌,这不, 绞尽脑汁想出了一个爬取新浪微博,并对爬取数据做简单统计的项目.一开始我自以为学习了点Python正则就可以搞定了,熟料在机器登陆上栽了跟头,从完全一头雾水到现在初步登陆获取到数据,整整历经了四五天.因为之前没搞过机器登陆方面的代码,所以这次项目的初步完成完全归功于网上的一些大神,我只是拾人牙慧,拼凑了几个大神的代码,另外加几行注释而已. # import 这边需要注意的是只有一个rsa这个模块是需要install的,

南邮JAVA程序设计实验1 综合图形界面程序设计

南邮JAVA程序设计实验1  综合图形界面程序设计 实验目的: 学习和理解JAVA SWING中的容器,部件,布局管理器和部件事件处理方法.通过编写和调试程序,掌握JAVA图形界面程序设计的基本方法. 实验内容: 设计和编写一个用于将人民币转换为等值的美元的程序,界面要求可以输入人民币的金额并可以得到转换后的结果.(每100美元等值买入人民币数:619.72) 实验代码: import java.awt.*; import java.awt.event.*; import java.math.*

于南邮平台游荡关于宽字节注入——骚操作

脚本名:unmagicquotes.py 作用:宽字符绕过 GPC addslashes12345 Example:* Input: 1′ AND 1=1* Output: 1%bf%27 AND 1=1–%20 今天早上在南邮平台游荡的时候,做了一题关于宽字节注入的题目,虽然宽字节注入属于很常见的题目 但是,大多数人使用的都是手工注入,我作为一个小萌新(手工注入太难了QAQ) 今天get到一个新的骚操作: 题目分析: . 首先:进行简单的手工注入操作: 可以看出这个属于典型的宽字节注入:关于宽