個人爬蟲進階

最近幾天一直在搞爬蟲,爬的是學校的網站,須要登陸。html

大致分爲三步:前端

1.  抓包python

先將打開網頁中的的整個流程,用抓包工具進行抓包,分析各個包中的內容,尤爲重視以POST方式發出去的包,post出的數據/headers/cookies。可以使用Foxfire瀏覽器的一個插件HTTPFox,對包的獲取及內容進行解析。json

2.  模擬登錄瀏覽器

本次對於學校網站的爬去在於模擬登錄,這裏使用的是python中的request模塊。cookie

關於request的模塊可到http://docs.python-requests.org/zh_CN/latest/user/advanced.html#advanced網絡

下面來講此次爬蟲模擬登錄的幾個關鍵步驟:session

建立一個Session對象:app

s=requests.session()

而後,將第一步中post須要獲得的數據獲取到。Post的數據可能不單單是須要輸入的帳號密碼,還有須要在網頁上隱藏的數據。好比此次爬蟲須要輸入的:jsp

postdata={
    "username":username,
    "password":password,
    "lt":lt,
    'dllt':'userNamePasswordLogin',
    'execution':execution,
    '_eventId':'submit',
    'rmShown':'1'
}

3. 將數據和headers一併傳遞的網絡中:

r2=s.post(self.url,headers=self.headers,data=postdata)

4. 而後就能夠進入登錄後界面了。能夠隨心所欲了,有沒有小激動。

但不要高興的太早,學校成績界面HTML中使用了動態頁面,動態頁面的HTML中是不具備所須要爬去的信息的。拿着該怎麼辦呢,好在天無絕人之路,如今有兩種方法能夠解決:一種是導入動態解析的模塊,進行解析;一種是直接經過分析所抓的包,分析最終頁面的url。網上有不少解決辦法,對於熟悉前端的猿們,這點應該不難。看來學校的界面也不是想爬就能爬的,不經歷風雨怎能見彩虹。

r3=s.get("http://yjs.njupt.edu.cn/epstar/app/template.jsp?mainobj=YJSXT/PYGL/CJGLST/V_PYGL_CJGL_KSCJHZB&tfile=KSCJHZB_CJCX_CD/KSCJHZB_XSCX_CD_BD&filter=V_PYGL_CJGL_KSCJHZB:WID=%275m3b6a22-nlcp49-ia4istlb-1-ia6fcwu4-t7h%27",headers=self.headers)

最終經過get方法將網頁頁面整個down了下來。

5.解析頁面,對於頁面的解析,有不少方式:正則/beautifulsoup等等

6.將所寫的過程封裝成方法進而造成類。

這是最終代碼:

#coding:utf-8
'''爬去教務網站成績及我的姓名學號'''

import re
import requests
import sys
import json

reload(sys)
sys.setdefaultencoding('utf8')

#模擬瀏覽器登陸學校教務網
class JiaoWuXiTongHtml(object):

    def __init__(self):
        self.url = "http://ids6.njupt.edu.cn/authserver/login?service=http://my.njupt.edu.cn/login.do"
        self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0'}
    #模擬登錄並下載頁面
    def downloadHtml(self,username,password):
        s=requests.session()
        r=s.get(self.url,headers=self.headers)
        ltlist=re.findall(r'<input type="hidden" name="lt" value="(LT-.*?-cas)"/', r.text, re.S)
        executionlist = re.findall(r'<input type="hidden" name="execution" value="(e\ds\d)".* ',r.text,re.S)
        lt = ltlist[0]
        execution = executionlist[0]
        #提交數據
        postdata={
            "username":username,
            "password":password,
            "lt":lt,
            'dllt':'userNamePasswordLogin',
            'execution':execution,
            '_eventId':'submit',
            'rmShown':'1'
        }
        r2=s.post(self.url,headers=self.headers,data=postdata) #提交數據進入登錄界面
        # print "*"*100    #分隔符
        r3=s.get("http://yjs.njupt.edu.cn/epstar/app/template.jsp?mainobj=YJSXT/PYGL/CJGLST/V_PYGL_CJGL_KSCJHZB&tfile=KSCJHZB_CJCX_CD/KSCJHZB_XSCX_CD_BD&filter=V_PYGL_CJGL_KSCJHZB:WID=%275m3b6a22-nlcp49-ia4istlb-1-ia6fcwu4-t7h%27",headers=self.headers)
        return r3.content

    #解析爬取得html
    def parseHtml(self,html):

        patt1=r'<font id=cj >(.*?)</font>'
        patt2=r'<font id=kcmc >(.*?)</font>'
        patt3 = r'''<font id="XM" style='width:210px' value=.*>(.*?)</font>'''
        patt4 = r'''<font id="XH" style='width:210px' value=.*>(.*?)</font>'''
        regx1=re.compile(patt1)
        regx2=re.compile(patt2)
        regx3=re.compile(patt3)
        regx4=re.compile(patt4)
        content1s=re.findall(regx1,html)
        content2s=re.findall(regx2,html)
        # name=re.findall(regx3,html)[0]+'name'#由於字典無序,做爲姓名學號的特殊標識
        # xuhao=re.findall(regx4,html)[0]
        list1=[]
        list2=[]
        #處理匹配的字符串,統一編碼
        for i in content2s:
            i = i.decode('utf8').rstrip(r'&nbsp;')
            list2.append(i)
        for i in content1s:
            i = i.decode('utf8')
            list1.append(i)

        d = dict(zip(list1,list2))#將數據存在該字典裏
        # d[name]=xuhao#將姓名/學號添加到字典

        return d

#主函數類
class SpiderMain(object):
    def __init__(self):
        self.html = JiaoWuXiTongHtml()

    def craw(self,name,password):
        htmlpage = self.html.downloadHtml(name,password)
        print htmlpage
        data = self.html.parseHtml(htmlpage)
        return data


if __name__ == '__main__':
    print '\nwelcome to use craw data:'
    name = raw_input('input username:')
    password = raw_input('input password:')
    a = SpiderMain()
    d = a.craw(name,password)
    # file1 = open('name.txt','wb+')
    # file1.write(str(d))
    # file1.close()
    print json.dumps(d).decode("unicode-escape")#顯示中文
相關文章
相關標籤/搜索