前一篇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. POI的XWPFParagraph.getRuns分段问题 多余逗号

    POI的XWPFParagraph.getRuns分段问题 2018年08月28日 09:49:32 银爪地海贼 阅读数:376   这是我的模板 后台打印出来是分段的 造成这样的原因是${name} ...

  2. Spring MVC使用Cors实现跨域

    在开发APP过程中,APP调用后端接口有跨域的问题,只要在spring-mvc.xml 文件中加入下面的配置即可: <!-- 解决API接口跨域问题配置 Spring MVC 版本必须是 4.2 ...

  3. python的dict()字典数据类型的方法详解以及案例使用

    一.之前的回顾 # int  数字 # str 字符串 # list 列表 # tuple 元组 # dict 字典 字典中最重要的方法 keys() values() items() get upd ...

  4. IDEA Mybatis plugin插件破解

    破解文件: 链接:https://pan.baidu.com/s/1J7asfLc5I0RBcoYX3_yNvQ 提取码:kjxv 使用方法: C:\Users\{你的用户名}\.IntelliJId ...

  5. 科学计算三维可视化---Traits(Event和button属性)

    Event和button属性 是两个专门用于处理事件的change属性 Event属性和其他Trait属性不一样 Button属性是由Event属性继承而来的 Event监听 from traits. ...

  6. python---基础知识回顾(八)数据库基础操作(sqlite和mysql)

    一:sqlite操作 SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以 ...

  7. bzoj 3309 反演

    $n=p_1^{a_1}p_2^{a_2}…p_k^{a_k},p_i$为素数,定义$f(n)=max(a_1,a_2…,a_k)$. 给定a,b<=1e7求$\sum\limits_{i=1} ...

  8. SQL - 查询某一字段值相同而另一字段值最大的记录

    有时需要以某一字段作为分组,筛选每一组的另一字段值最大(或最小)的记录.例如,有如下表 app,存储了 app 的 ID.名称.版本号等信息.现在要筛选出每个 app 版本最大的记录. 方法一 SEL ...

  9. 【Foreign】Rectangle [KD-tree]

    Rectangle Time Limit: 50 Sec  Memory Limit: 512 MB Description Input Output Sample Input 0 4 2 0 2 1 ...

  10. Ubuntu 12.04 更新源的方法及地址

    本文章转自:http://www.maybe520.net/blog/424/ 安装好ubuntu 12.04之后,可以联网之后,马上要做的最重要的事情之一就是配置更新源列表,这样以后安装更新或者软件 ...