个人爬虫进阶

最近几天一直在搞爬虫,爬的是学校的网站,须要登陆。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")#显示中文
相关文章
相关标签/搜索