首頁  >  文章  >  後端開發  >  [Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

黄舟
黄舟原創
2017-01-21 14:42:331607瀏覽

先來談談我們學校的網站:

http://jwxt.sdu.edu.cn:7777/zhxt_bks/zhxt_bks.html

查詢成績需要登錄,然後顯示各學科成績,但是只顯示成績而沒有績點,也就是加權平均分數。

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

顯然這樣手動計算績點是一件非常麻煩的事情。所以我們可以用Python做一個爬蟲來解決這個問題。

1.決戰前夜

先來準備一下工具:HttpFox插件。

這是一款http協定分析插件,分析頁面請求與回應的時間、內容、以及瀏覽器用到的COOKIE等。

以我為例,安裝在火狐上即可,效果如圖:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)


可以非常直觀的查看相應的資訊。

點選start是開始偵測,點選stop暫停偵測,點選clear清除內容。

一般在使用之前,點擊stop暫停,然後點擊clear清屏,確保看到的是存取目前頁面所獲得的資料。

2.深入敵後

下面就去山東大學的成績查詢網站,看一看在登入的時候,到底發送了那些訊息。

先來到登入頁面,把httpfox打開,clear之後,點選start開啟偵測:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

輸入完了個人訊息,確保httpfox處於開啟狀態,然後點擊確定提交訊息,實現登入。

這個時候可以看到,httpfox檢測到了三條訊息:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

這時點擊stop鍵,確保捕獲到的是訪問該頁面之後反饋的數據,以便我們做爬蟲的時候模擬登陸使用。


3.庖丁解牛

乍一看我們拿到了三個數據,兩個是GET的一個是POST的,但是它們到底是什麼,應該怎麼用,我們還一無所知。

所以,我們需要挨個查看一下捕獲到的內容。

先看POST的訊息:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

既然是POST的訊息,我們就直接看PostData即可。

可以看到一共POST兩個數據,stuid和pwd。

並且從Type的Redirect to可以看出,POST完畢之後跳到了bks_login2.loginmessage頁面。


由此看出,這個資料是點選確定之後提交的表單資料。

點擊cookie標籤,看看cookie訊息:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

沒錯,收到了一個ACCOUNT的cookie,並且在session結束之後自動銷毀。

那麼提交之後收到了哪些資訊呢?

我們來看看後面的兩個GET數據。

先看第一個,我們點選content標籤可以查看收到的內容,是不是有一種生吞活剝的快感-。 -HTML來源碼暴露無疑了:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

看來這個只是顯示頁面的html源碼而已,點擊cookie,查看cookie的相關資訊:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

啊哈,原來html頁面的內容是發送了

之後才接受到的。 [Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

再來看看最後一個接收到的資訊:


大致看了一下應該只是一個叫做style.css的css文件,對我們沒有太大的作用。

4.冷靜應戰

既然已經知道了我們向伺服器發送了什麼數據,也知道了我們接收到了什麼數據,基本的流程如下:

首先,我們POST學號和密碼--->然後傳回cookie的值

然後發送cookie給伺服器--->傳回頁面資訊。

取得到成績頁的數據,用正規表示式將成績和學分單獨取出併計算加權平均數。

OK,看上去好像很簡單的樣紙。那下面我們就來試試看吧。

但是在實驗之前,還有一個問題沒有解決,就是POST的資料到底送到哪裡了? [Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

再來看一下當初的頁面:

🎜很明顯是用一個html框架來實現的,也就是說,我們在地址欄看到的地址並不是右邊提交表單的地址。 🎜🎜那麼怎樣才能得到真正的地址-。 -右鍵查看頁面原始碼:🎜

嗯沒錯,那個name="w_right"的就是我們要的登入頁面。

網站的原來的地址是:

http://jwxt.sdu.edu.cn:7777/zhxt_bks/zhxt_bks.html

所以,真正的表單提交的地址應該是:

.sdu.edu.cn:7777/zhxt_bks/xk_login.html

輸入一看,果不其然:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

靠居然是清華大學的選課系統。 。 。目測是我校懶得做頁面了就直接借了。 。結果連標題都不改一下。 。 。

但是這個頁面依舊不是我們需要的頁面,因為我們的POST資料提交到的頁面,應該是表單form的ACTION中提交到的頁面。

也就是說,我們需要查看源碼,來知道POST資料到底發送到哪裡:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

嗯,目測這個才是提交POST資料的位址。

整理到網址列中,完整的網址應如下:

http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login


(取得的方式很簡單,在火狐瀏覽器中直接點擊那個連結就能看到這個連結的地址了)



5.小試牛刀


接下來的任務就是:用python模擬發送一個POST的數據並取到返回​​的cookie值。


關於cookie的操作可以看看這篇部落格文章:

http://blog.csdn.net/wxg694175346/article/details/8925978


的接收,然後寫出源碼如下:

# -*- coding: utf-8 -*-  
#---------------------------------------  
#   程序:山东大学爬虫  
#   版本:0.1  
#   作者:why  
#   日期:2013-07-12  
#   语言:Python 2.7  
#   操作:输入学号和密码  
#   功能:输出成绩的加权平均值也就是绩点  
#---------------------------------------  
  
import urllib    
import urllib2  
import cookielib  
  
cookie = cookielib.CookieJar()    
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))  
  
#需要POST的数据#  
postdata=urllib.urlencode({    
    'stuid':'201100300428',    
    'pwd':'921030'    
})  
  
#自定义一个请求#  
req = urllib2.Request(    
    url = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login',    
    data = postdata  
)  
  
#访问该链接#  
result = opener.open(req)  
  
#打印返回的内容#  
print result.read()

如此這般之後,再看看運行的效果:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)ok,如此這般,我們就算模擬登陸成功了。


6.偷天換日


接下來的任務就是用爬蟲獲取到學生的成績。

再來看看來源網站。

開啟HTTPFOX之後,點擊查看成績,發現捕獲到瞭如下的數據:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

GET的數據,點擊查看可以發現的內容。


而獲取到的頁面鏈接,從頁面源代碼中右鍵查看元素,可以看到點擊鏈接之後跳轉的頁面(火狐瀏覽器只需要右鍵,“查看此框架”,即可) :

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

因此可以得到查看成績的連結如下:


http://jwxt.sdu.edu.edu.edu.edu.


7.萬事俱備

現在萬事俱備啦,所以只需要把連結應用到爬蟲裡面,看看能否查看到成績的頁面。

從httpfox可以看到,我們發送了一個cookie才能返回成績的信息,所以我們就用python模擬一個cookie的發送,以此來請求成績的信息:

# -*- coding: utf-8 -*-  
#---------------------------------------  
#   程序:山东大学爬虫  
#   版本:0.1  
#   作者:why  
#   日期:2013-07-12  
#   语言:Python 2.7  
#   操作:输入学号和密码  
#   功能:输出成绩的加权平均值也就是绩点  
#---------------------------------------  
  
import urllib    
import urllib2  
import cookielib  
  
#初始化一个CookieJar来处理Cookie的信息#  
cookie = cookielib.CookieJar()  
  
#创建一个新的opener来使用我们的CookieJar#  
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))  
  
#需要POST的数据#  
postdata=urllib.urlencode({    
    'stuid':'201100300428',    
    'pwd':'921030'    
})  
  
#自定义一个请求#  
req = urllib2.Request(    
    url = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login',    
    data = postdata  
)  
  
#访问该链接#  
result = opener.open(req)  
  
#打印返回的内容#  
print result.read()  
  
#打印cookie的值  
for item in cookie:    
    print 'Cookie:Name = '+item.name    
    print 'Cookie:Value = '+item.value  
  
      
#访问该链接#  
result = opener.open('http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre')  
  
#打印返回的内容#  
print result.read()

按下F5運行即可,看按下F5運行即可,看按下F5運行即可,看看捕獲的資料吧:

既然這樣就沒有什麼問題了吧,用正則表達式將數據稍稍處理一下,取出學分和相應的分數就可以了。

8.手到擒來[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

這麼一大堆html源碼顯然是不利於我們處理的,下面要用正規表示式來摳出必須的資料。

關於正規表示式的教學可以看看這篇部落格文章:

http://blog.csdn.net/wxg694175346/article/details/8929576

既然如此,用正则表达式就易如反掌了。


我们将代码稍稍整理一下,然后用正则来取出数据:

# -*- coding: utf-8 -*-  
#---------------------------------------  
#   程序:山东大学爬虫  
#   版本:0.1  
#   作者:why  
#   日期:2013-07-12  
#   语言:Python 2.7  
#   操作:输入学号和密码  
#   功能:输出成绩的加权平均值也就是绩点  
#---------------------------------------  
  
import urllib    
import urllib2  
import cookielib  
import re  
  
class SDU_Spider:    
    # 申明相关的属性    
    def __init__(self):      
        self.loginUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login'   # 登录的url  
        self.resultUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre' # 显示成绩的url  
        self.cookieJar = cookielib.CookieJar()                                      # 初始化一个CookieJar来处理Cookie的信息  
        self.postdata=urllib.urlencode({'stuid':'201100300428','pwd':'921030'})     # POST的数据  
        self.weights = []   #存储权重,也就是学分  
        self.points = []    #存储分数,也就是成绩  
        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookieJar))  
  
    def sdu_init(self):  
        # 初始化链接并且获取cookie  
        myRequest = urllib2.Request(url = self.loginUrl,data = self.postdata)   # 自定义一个请求  
        result = self.opener.open(myRequest)            # 访问登录页面,获取到必须的cookie的值  
        result = self.opener.open(self.resultUrl)       # 访问成绩页面,获得成绩的数据  
        # 打印返回的内容  
        # print result.read()  
        self.deal_data(result.read().decode('gbk'))  
        self.print_data(self.weights);  
        self.print_data(self.points);  
  
    # 将内容从页面代码中抠出来    
    def deal_data(self,myPage):    
        myItems = re.findall(&#39;<TR>.*?<p.*?<p.*?<p.*?<p.*?<p.*?>(.*?)</p>.*?<p.*?<p.*?>(.*?)</p>.*?</TR>&#39;,myPage,re.S)     #获取到学分  
        for item in myItems:  
            self.weights.append(item[0].encode(&#39;gbk&#39;))  
            self.points.append(item[1].encode(&#39;gbk&#39;))  
  
              
    # 将内容从页面代码中抠出来  
    def print_data(self,items):    
        for item in items:    
            print item  
              
#调用    
mySpider = SDU_Spider()    
mySpider.sdu_init()

水平有限,,正则是有点丑,。运行的效果如图:

[Python]網路爬蟲(十):一個爬蟲的誕生全過程(以山東大學績點運算為例)

ok,接下来的只是数据的处理问题了。。

9.凯旋而归

完整的代码如下,至此一个完整的爬虫项目便完工了。

# -*- coding: utf-8 -*-  
#---------------------------------------  
#   程序:山东大学爬虫  
#   版本:0.1  
#   作者:why  
#   日期:2013-07-12  
#   语言:Python 2.7  
#   操作:输入学号和密码  
#   功能:输出成绩的加权平均值也就是绩点  
#---------------------------------------  
  
import urllib    
import urllib2  
import cookielib  
import re  
import string  
  
  
class SDU_Spider:    
    # 申明相关的属性    
    def __init__(self):      
        self.loginUrl = &#39;http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login&#39;   # 登录的url  
        self.resultUrl = &#39;http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre&#39; # 显示成绩的url  
        self.cookieJar = cookielib.CookieJar()                                      # 初始化一个CookieJar来处理Cookie的信息  
        self.postdata=urllib.urlencode({&#39;stuid&#39;:&#39;201100300428&#39;,&#39;pwd&#39;:&#39;921030&#39;})     # POST的数据  
        self.weights = []   #存储权重,也就是学分  
        self.points = []    #存储分数,也就是成绩  
        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookieJar))  
  
    def sdu_init(self):  
        # 初始化链接并且获取cookie  
        myRequest = urllib2.Request(url = self.loginUrl,data = self.postdata)   # 自定义一个请求  
        result = self.opener.open(myRequest)            # 访问登录页面,获取到必须的cookie的值  
        result = self.opener.open(self.resultUrl)       # 访问成绩页面,获得成绩的数据  
        # 打印返回的内容  
        # print result.read()  
        self.deal_data(result.read().decode(&#39;gbk&#39;))  
        self.calculate_date();  
  
    # 将内容从页面代码中抠出来    
    def deal_data(self,myPage):    
        myItems = re.findall(&#39;<TR>.*?<p.*?<p.*?<p.*?<p.*?<p.*?>(.*?)</p>.*?<p.*?<p.*?>(.*?)</p>.*?</TR>&#39;,myPage,re.S)     #获取到学分  
        for item in myItems:  
            self.weights.append(item[0].encode(&#39;gbk&#39;))  
            self.points.append(item[1].encode(&#39;gbk&#39;))  
  
    #计算绩点,如果成绩还没出来,或者成绩是优秀良好,就不运算该成绩  
    def calculate_date(self):  
        point = 0.0  
        weight = 0.0  
        for i in range(len(self.points)):  
            if(self.points[i].isdigit()):  
                point += string.atof(self.points[i])*string.atof(self.weights[i])  
                weight += string.atof(self.weights[i])  
        print point/weight  
  
              
#调用    
mySpider = SDU_Spider()    
mySpider.sdu_init()

以上就是 [Python]网络爬虫(十):一个爬虫的诞生全过程(以山东大学绩点运算为例)的内容,更多相关内容请关注PHP中文网(www.php.cn)!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn