前一篇http://www.cnblogs.com/liyinggang/p/6094338.html 使用了爬虫爬取hdu 的代码,今天实现了将数据向hdu 提交的功能,接下来就是需要将两个功能合并了.

这里感谢綦大神的博客, 不仅ACM玩得厉害,而且还精通各种语言.我辈楷模,我从他这里学会了怎么使用 chrome 抓包.按 F12,然後去找到NetWork就行了.然后就可以看到各种信息.

比如在hdu的登录界面我们就可以看到如下信息:

然后可以根据这些信息确定这个网页是需要Post方法还是GET方法,还有header的信息,以及发送数据的格式等等.

我们总共是有三个网页需要进行解析:

登录

网页:http://acm.hdu.edu.cn/userloginex.php?action=login
数据: username=用户名&userpass=密码&login=Sign+In

提交:

网页:http://acm.hdu.edu.cn/submit.php?action=submit
数据:problemid=pid&language=lang&usercode=code&check=

然后获取状态的页面,下载好了然后再用正则表达式去匹配.这里对于每个网页的下载,特别是这个 status 页面,我用自己写的Download 函数下不下来,可能是HDU做了什么防爬虫的手段...这里关于传输数据,下载在网上参考了别人写的代码才搞定,但是它的正则表达式是有问题的...说说这个正则表达式吧,真的弄了我好久,因为我一直想很贪心的把自己的提交记录一下子就给匹配到,这样反而做不好 (反正我是弄不好一句话去匹配,总是匹配多了 = =) 后来我直接先把所有的 <tr ** > </tr> 标签弄出来,然后到每个里面找我的提交记录,这样分开处理要好多了,然后找状态就很简单了.这里网页里面如果有 \n 符用 .*? 是匹配不到的,因为 . 是不包括换行符的所有字符,所以要用 [\s\S]或者 [\d\D]这种.

/**这一段是更新,不看也无妨**/

/*************更新*******************************/
这里的话有另一种的方法可以得到我们所需的表单提交时所需的信息,我们能够利用 lxml.html 的 cssselect 进行解析。
/*********************************************/
#coding:utf-8
import urllib2 import lxml.html __author__ = 'liyinggang' def getInputFromForm(html):
'''This method is to use all the input tags of the form
'''
tree = lxml.html.fromstring(html)
data = {}
for e in tree.cssselect('form input'): #使用css选择器遍历表单所有 input标签
if e.get('name'):
data[e.get('name')] = e.get('value')
return data if __name__ == '__main__':
url = 'http://acm.hdu.edu.cn/userloginex.php'
html = urllib2.urlopen(url).read()
getInputFromForm(html)

/*********************/

附上code(^_^希望大家学习爬虫不要不停地刷hdu界面,那样的话对大家都不好,hdu的维护靠大家~):

#coding:utf-8
'''
Created on 2016年11月29日 @author: liyinggang
'''
import cookielib, logging
from time import sleep
import urllib2, urllib, re seed_url = "http://acm.hdu.edu.cn"
login_url = "/userloginex.php?action=login"
submit_url = "/submit.php?action=submit"
status_url ="/status.php"
class HDU: def __init__(self,username,password):
self.username= username
self.password = password
self.code = None
self.pid = 1000
self.retry=False
cj=cookielib.CookieJar()
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj),urllib2.HTTPHandler)
#urllib2.urlopen()函数不支持验证、cookie或者其它HTTP高级功能。要支持这些功能,必须使用build_opener()函数创建自定义Opener对象。
urllib2.install_opener(opener) #这句必须加,开始一直登录不上,但是具体为什么依旧待弄清
self.headers ={"User-Agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36"} def login(self):
postdata = {'username': self.username,
'userpass': self.password,
'login': 'Sign In'}
postdata = urllib.urlencode(postdata)
try:
request=urllib2.Request(seed_url+login_url,postdata,self.headers)
response = urllib2.urlopen(request, timeout=10)
html = response.read()
if html.find('Sign Out')==-1:
logging.error('login failed')
return False
print 'login success!'
return True
except:
logging.error('login failed')
return False def getstatus(self):
postdata = {'user': self.username,
'lang': 0,
'first': '',
'pid': '',
'status': 0}
postdata = urllib.urlencode(postdata)
status = ''
waitstatus = ['Compiling','Queuing','Running']
cnt = 0
#regex = '(<tr( bgcolor=#D7EBFF | )align=center >){1}(<td.*?</td>){2}<td><font color=.*?>(.*?)</font></td>(<td.*?</td>){5}<td class=fixedsize><a href="/userstatus.php\?user=%s">(?=.*?</a></td>)'%self.username
while True:
try:
regex = '<table[^>]+>([\s\S]*?)</table>'
request=urllib2.Request(seed_url+status_url,postdata,self.headers)
response = urllib2.urlopen(request, timeout=10)
html = response.read()
table = re.findall(regex, html)[1]
regex = '<tr[^>]+>([\s\S]*?)</tr>'
L = re.findall(regex, table)
result = L[1]
regex = str(self.username)
flag = True
for i in L:
if re.search(regex, i):
flag = False
result = i
break
#print result
if flag:
status = 'UNKNOWN ERROR'
break
regex = '<font[^>]+>(.*?)</font>'
status = re.findall(regex, result)[0]
if status not in waitstatus or cnt>=50:
break
cnt+=1
sleep(10)
except:
print '程序发生错误终止'
return False
print 'hduoj problem '+str(self.pid)+':'+status
if status=='Compilation Error' and self.retry==False:
self.retry = True
self.submit(pid=self.pid,lang=2,code=self.code)
if self.getstatus(): #再用c++交一次
return True
if status=='Accepted':
return True
return False def submit(self,pid,lang,code):
postdata = {'problemid':pid,
'language' :lang,
'usercode' : code,
'check': ''
}
self.code = code
self.pid = pid
postdata = urllib.urlencode(postdata)
try:
request=urllib2.Request(seed_url+submit_url,postdata,self.headers)
response = urllib2.urlopen(request, timeout=10)
sleep(1)
if(response.code!=200 and response.code!=302):
logging.error("submit fail!")
return False
except:
logging.error("submit fail!")
return False
print 'submit success!'
return True

在blog里面提取想要代码(开头的链接已经有这部分功能了,不过整合一下,如果有大佬能提出修改意见,帮我提供更好的正则表达式当然再感谢不过,宝宝心里苦,博客园的代码解析出来有时候带有行号,所以干脆不要了,心塞塞(/TДT)/ ):

def getcode(url):
'''返回值的第一个参数代表code,第二个参数代表用什么语言提交, 0是G++,5是 Java
'''
D = Downloader(user_agent='lyg')
html = D(url)
tree = lxml.html.fromstring(html)
texts = tree.cssselect('pre')
texts.extend(tree.cssselect('p > textarea.cpp'))
regex0 = re.compile('^(#include([\s\S]*)main()[\d\D]+)') #如果是代码里面一定包含 main() 函数
regex1 = re.compile('^(#import([\s\S]*)main()[\d\D]+)')
for text in texts:
text = text.text_content()
pattern0 = re.search(regex0, text)
pattern1 = re.search(regex1, text)
if(pattern0):
text = pattern0.group(1)
return [text,0]
if(pattern1):
text = pattern1.group(1)
return [text,5]
return None

测试代码:

#coding:utf-8
'''
Created on 2016年11月29日 @author: admin
'''
from HDU import HDU
from time import sleep
lang = 0
pid = 1000
code = '''
#include<stdio.h>
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
printf("%d\\n",a+b);
return 0;
}
'''
hdu = HDU('***','***')
if(hdu.login()):
if(hdu.submit(pid, lang, code)):
sleep(2)
hdu.getstatus()

下面是我完成之后的代码的运行功能(AC率挺高的,嘻嘻,不过为了HDU的服务器我就不放源代码了,反正博客里都写好了(。・ω・。) ):

Python爬虫之HDU提交数据的更多相关文章

  1. java调用Linux执行Python爬虫,并将数据存储到elasticsearch--(环境脚本搭建)

    java调用Linux执行Python爬虫,并将数据存储到elasticsearch中 一.以下博客代码使用的开发工具及环境如下: 1.idea: 2.jdk:1.8 3.elasticsearch: ...

  2. Python爬虫丨大众点评数据爬虫教程(1)

    大众点评数据获取 --- 基础版本 大众点评是一款非常受普罗大众喜爱的一个第三方的美食相关的点评网站. 因此,该网站的数据也就非常有价值.优惠,评价数量,好评度等数据也就非常受数据公司的欢迎. 今天就 ...

  3. python爬虫——汽车之家数据

    相信很多买车的朋友,首先会在网上查资料,对比车型价格等,首选就是"汽车之家",于是,今天我就给大家扒一扒汽车之家的数据: 一.汽车价格: 首先获取的数据是各款汽车名称.价格范围以及 ...

  4. 使用python爬虫爬取股票数据

    前言: 编写一个爬虫脚本,用于爬取东方财富网的上海股票代码,并通过爬取百度股票的单个股票数据,将所有上海股票数据爬取下来并保存到本地文件中 系统环境: 64位win10系统,64位python3.6, ...

  5. python爬虫爬取天气数据并图形化显示

    前言 使用python进行网页数据的爬取现在已经很常见了,而对天气数据的爬取更是入门级的新手操作,很多人学习爬虫都从天气开始,本文便是介绍了从中国天气网爬取天气数据,能够实现输入想要查询的城市,返回该 ...

  6. python爬虫——爬取网页数据和解析数据

    1.网络爬虫的基本概念 网络爬虫(又称网络蜘蛛,机器人),就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序.只要浏览器能够做的事情,原则上,爬虫都能够做到. 2 ...

  7. Python爬虫丨大众点评数据爬虫教程(2)

    大众点评数据爬虫获取教程 --- [SVG映射版本] 前言: 大众点评是一款非常受大众喜爱的一个第三方的美食相关的点评网站.从网站内可以推荐吃喝玩乐优惠信息,提供美食餐厅.酒店旅游.电影票.家居装修. ...

  8. Python爬虫之-动态网页数据抓取

    什么是AJAX: AJAX(Asynchronouse JavaScript And XML)异步JavaScript和XML.过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新.这意 ...

  9. Python爬虫10-页面解析数据提取思路方法与简单正则应用

    GitHub代码练习地址:正则1:https://github.com/Neo-ML/PythonPractice/blob/master/SpiderPrac15_RE1.py 正则2:match. ...

随机推荐

  1. C标准库函数--文件IO操作函数。

    C标准库文件读写函数总结:都是对文件流进行输入输出的函数分为对文件的有格式读写以及无格式读写 一.文件的无格式读写根据每次读写字符的数量,分为三类:1.按字符读写文件 按字符读有三个函数:以下三个函数 ...

  2. C++下实现同接口下多个类作为参数的调用和传参

    /* 实现同接口下不同类的对象的转移 定义类的接口 定义多个继承该接口的类 定义管理类,把接口当作类型, 传入该接口下各种类的对象,进行操作 */ #include<iostream> # ...

  3. P3097 [USACO13DEC]最优挤奶Optimal Milking

    P3097 [USACO13DEC]最优挤奶Optimal Milking 题意简述:给定n个点排成一排,每个点有一个点权,多次改变某个点的点权并将最大点独立集计入答案,输出最终的答案 感谢@zht4 ...

  4. Java锁及AbstractQueuedSynchronizer源码分析

    一,Lock 二,关于锁的几个概念 三,ReentrantLock类图 四,几个重要的类 五,公平锁获取 5.1 lock 5.2 acquire 5.3 tryAcquire 5.3.1 hasQu ...

  5. HDU 5143 DFS

    分别给出1,2,3,4   a, b, c,d个 问能否组成数个长度不小于3的等差数列. 首先数量存在大于3的可以直接拿掉,那么可以先判是否都是0或大于3的 然后直接DFS就行了,但是还是要注意先判合 ...

  6. c# 判断一个数是不是质数或者求一个数的公约数的算法

    一个数是不是质数,就是判断一个数除了1和它本身还有没有其他的约数,如果有则是合数,否则是质数.其实本质都是求公约数. 求公约数是什么思路呢,就是找比它小的数不断尝试,能被整除则是其约数,否则继续尝试, ...

  7. JS设计模式——11.适配器模式

    适配器模式概述 适配器模式可用来在现有接口和不兼容的类之间进行适配.使用这种模式的对象又叫包装器(wrapper). 适配器特点 从表面看,适配器模式很像门面模式.她们都要对别的对象进行包装并改变其呈 ...

  8. oracle06

    1. Oracle的体系结构 - 了解 1.1. Oracle数据库和Oracle实例 Oracle 服务器软件部分由两大部分组成, Oracle 数据库 和 Oracle 实例. 两者的解释如下: ...

  9. Mysql注入root权限直接写一句话马

    首先我们的找到一个有注入的站:这里我用自己搭建的环境表示:大家不要乱来 http://localhost/pentest/sql/sql_injection_get.php?id=1 发现是root权 ...

  10. 【codeforces】【比赛题解】#960 CF Round #474 (Div. 1 + Div. 2, combined)

    终于打了一场CF,不知道为什么我会去打00:05的CF比赛…… 不管怎么样,这次打的很好!拿到了Div. 2选手中的第一名,成功上紫! 以后还要再接再厉! [A]Check the string 题意 ...