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