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

来源:互联网 发布:空姐收入 知乎 编辑:程序博客网 时间:2024/06/11 00:33

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

 

利用用pythonurlliburllib2模块实现网络爬虫比较简单:

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

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

       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 webbrowserimport reimport 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,不需要改动程序,只需要改动文件即可。


这个程序的效果如下:




 

0 0