您的位置:首页 > 编程语言 > Python开发

利用python爬虫抓取OJ上做题信息(扩展版)

2014-01-14 10:50 796 查看
网络爬虫主要是抓取指定的html网页后从获取到的网页中利用正则表达式提取我们需要的信息。Python给我提供了几个模块供我们使用,在源代码中可以看到它们的用法。

利用用python的urllib和urllib2模块实现网络爬虫比较简单:

a、写出合适的正则表达式

b、用urllib2的urlopen函数打开指定的网页并将网页内容读取到字符串中

c、用re模块的findall查找和正则表达式相匹配的内容、并将内容记录到list中

d、处理list中的数据

1.获取html网页:

page = urllib.urlopen(url)

html = page.read()

2.利用python提供的正则表达式来提取相应的内容

re.findall(imgre,html)

其中imgre为正则表达式,html为我们在1中获得的网页的源代码。上面的式子返回的是我们获取的内容列表。

import webbrowser
import re
import urllib

#获取hdu网页
def getHtml_hdu(url):
page = urllib.urlopen(url)
html = page.read()
#unicodehtml = html.decode("utf-8")
#return unicodehtml
return html

#获取poj网页
def getHtml_poj(url):
page = urllib.urlopen(url)
html = page.read()
#unicodehtml = html.decode("utf-8")
#return unicodehtml
return html

#获取cug网页
def getHtml_cug(url):
page = urllib.urlopen(url)
html = page.read()
unicodehtml = html.decode("utf-8")
return unicodehtml

#获取hdu中用户信息
def zhenghe_hdu(str1,userid,imgre):
html=getHtml_hdu( str1+userid )
return re.findall(imgre,html)

#获取cug中用户信息
def zhenghe_cug(str1,userid,imgre):
html=getHtml_cug( str1+userid )
return re.findall(imgre,html)

#获取poj中用户信息
def zhenghe_poj(str1,userid,imgre):
html =getHtml_poj( str1+ userid)
return re.findall(imgre,html)

#文件读出用户账号进行统计
def readFile(result_cug,result_hdu,result_poj):
file_object = open("users.txt",'r')

reg_cug = r'<td>Solved<td align=center><a href=.*?>(.*?)</a>'
imgre_cug = re.compile(reg_cug)
reg_hdu = r'<tr><td>Problems Solved</td><td align=center>(.*?)</td></tr>'
imgre_hdu = re.compile(reg_hdu)
reg_poj = '<tr><td width=15% align=left>Solved:</td>[\s\S]*?<td align=center width=25%><a href=.*?>(.+?)</a></td>'
imgre_poj = re.compile(reg_poj)

#将结果输出到html网页
html = open('OJ.html', 'w')
html.write("""
<html>
<head>
<title>cug--hdu--poj统计</title>
<style>img{float:left;margin:5px;}</style>
</head>
<body>
""")

html.write("""
<center><table width=50%><tr><td colspan=3 align=left>
</form></td><td colspan=3 align=right>
</td></tr><tr class='toprow'>
<td><b>Account</b>
<td><b>cugOJ</b>
<td><b>hdOj</b>
<td><b>poj</b>
<td><b>sum</b>
""")

alist = []  #定义一个列表
for line in file_object:
line=line.strip('\n')    #去掉读取的每行的"\n"

list_hdu = zhenghe_hdu(result_hdu,line,imgre_hdu)
list_cug = zhenghe_cug(result_cug,line,imgre_cug)
list_poj = zhenghe_poj(result_poj,line,imgre_poj)

if len(list_hdu) == 0:
number_hdu = 0
else:
number_hdu = eval(list_hdu[0])

if len(list_cug) == 0:
number_cug = 0
else:
number_cug = eval(list_cug[0])

if len(list_poj) == 0:
number_poj = 0
else:
number_poj = eval(list_poj[0])

alist.append([line,number_cug,number_hdu,number_poj,number_cug+number_hdu+number_poj])
print "处理完一个用户信息"
for i in range(len(alist)):    #冒泡排序
for j in range(len(alist)):
if alist[i][4] > alist[j][4]:
tmp = alist[i]
alist[i] = alist[j]
alist[j] = tmp

for lst in alist:   #输出到网页
html.write("<p></p>")
html.write("<tr>")
html.write("<td>%s </td>" % lst[0] )
html.write("<td>%s </td>" % str(lst[1]) )
html.write("<td>%s </td>" % str(lst[2]) )
html.write("<td>%s </td>" % str(lst[3]) )
html.write("<td>%s </td>" % str(lst[4]) )
html.write("</table></body><ml>")

html.write('</body></html>')
html.close()
webbrowser.open_new_tab('OJ.html') #自动打开网页

result_hdu = "http://acm.hdu.edu.cn/userstatus.php?user="
result_cug = "http://acm.cug.edu.cn/JudgeOnline/userinfo.php?user="
result_poj = "http://poj.org/userstatus?user_id="

print "正在生成html网页......"
readFile(result_cug,result_hdu,result_poj)
print "html网页生成完毕,自动打开"


这个程序与之前写的一篇利用python爬虫抓取OJ信息(终结版)有一点不同的是这个程序的输入txt文件略有不同,增强了扩展性。先看看这个输入文件的格式:



实际上,输入还是具有一定的扩展性的,我们可以选择任意输入哪一个OJ,以及任意数量的OJ,不需要改动程序,只需要改动文件即可。

这个程序的效果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: