Python爬虫之模拟登陆

女神找我倾诉,实验室实验选不上,刚出来就被秒了,让我帮她选实验,我想我这万年单身的手速估计还是抢不过我这些师兄们,干脆写一个脚本吧,这样以后女神就找我选实验了,废话少说,切入主题,看这篇教程首先得保证你有Python基础,我尽量会写的通俗易懂,记录下思考的整个过程。

先来看一个简单的爬虫脚本

先不要想这个复杂的功能,我们想想能不能用Python浏览一个网页,就从最简单的抓取百度主页开始。PS:要用Python3哦~

import urllib.request

url = "http://www.baidu.com"
data = urllib.request.urlopen(url)
print(data.read().decode('UTF-8'))

上述代码的输出就是百度主页的html代码,对于爬虫的类库,不懂直接可以套用,这里我来解释一下编码的问题,看你需要爬的网页源码,Google浏览器右键检查,开头会有<meta charset="***">其中*就是网页的编码方式,因为Python内部使用unicode编码,所以要转为网页编码方式。


深入一点-模拟登陆

现在正式切入我们要实现的脚本,模拟登陆网站,然后模拟提交数据。先大概解释一下流程,我们登陆网站时,输入账号密码,网站会给浏览器发送一个cookie的东西,浏览器下次访问网页时,会将这个cookie发送给服务器,服务器就会知道是谁访问它了,所以我们模拟的时候,最关键的就是把这个cookie存起来。先看源码:

import urllib.request
import http.cookiejar
import urllib.parse

postData = {
        'username': '***',
        'pass': '***',
        'password': '***'
        }

url = '***'

cookie = http.cookiejar.CookieJar()
openner = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie))
headers = {
        'User-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
        }
request = urllib.request.Request(url, urllib.parse.urlencode(postData).encode(), headers)
r = openner.open(request)
print(r.read().decode('UTF-8'))

为了避嫌,这里我讲网页链接去掉,注意到账号和密码是保存在postData的字典中,还需要header参数,其他都是固定写法,没什么好解释的,下面我主要说明这postData和header参数是怎么构造的。

用Google浏览器打开你要登陆的网页,右键检查,点network选项
这里写图片描述

输入账号和密码,点登陆,这时候可以看到右侧抓取了内容,我们点第一个,点击就OK
这里写图片描述

现在可以看到我们构建的postData和header是从哪里来的了吧,postData的内容要保证一样,header可以不用全部构建,一般构建User-Agent和Referer就够了,如果你还爬不进去,不妨再加点别的参数试试。


更进一步-模拟post提交参数

经过上面的步骤,相信我们都可以登录进入网页了,下面我们要做的就是如何自动的填写参数,然后提交到网站上去。先看这部分的代码实现:

exUrl = "http://atc.hust.edu.cn:8080/lioms4hz/order/load?id=5"
exPostData = {
        'proSource': '111',
        'proNum': '111',
        'proName': '111',
        'sampleName': '111',
        'sampleCount': '111',
        'sampleDetail': '111',
        'sampleImg': '',
        'dpId': '50',
        'testDate': '2017-04-17',
        'startTime': '14:00:00',
        'endTime': '16:00:00',
        'startTime1': '',
        'endTime1': '',
        'startTime2': '',
        'endTime2': '',
        'remarks': '111',
        'uiid': '1784',
        'diid': '5',
        'parentid': '154',
        'duser': '474',
        'query': '1'
        }
exheaders = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
        'Referer': '***',
        'Origin': '***'
        }
exRequest = urllib.request.Request(exUrl, urllib.parse.urlencode(exPostData).encode(), exheaders)
exr = openner.open(exRequest)
response = exr.read().decode('UTF-8')

对于post的数据和header的参数的选择,经过上述的步骤相信都可以解决了,这里要注意的时,我们再次访问网站的时候需要要来的cookie,exr = openner.open(exRequest) 这一行代码可以保证将原来保存的cookie再次提交到网站。


总结

OK!写到这里,相信大部分人可以完成一个简单的爬虫程序了,当然爬虫的功能不仅仅局限于这里,当获取一个网页的html源码时,我们可以利用正则表达式,获取对我们有用的信息,从而可以完成更加复杂的功能。

将实现的整个代码上传到服务器上,再服务器安装Python3,可以利用crontab定时任务定时执行我们的脚本,比如说女神的实验是晚上9点开始选,那我们可以设定9点开始执行,命令如下:

[root@localhost ~]# crontab -e
0 21 * * * /bin/python3 /home/test.py > /home/test.log

crontab具体的配置过程可以看我的另一篇博客
http://blog.csdn.net/hxl_1993/article/details/52024943

下面帖出我实现的整个代码,为了保证万无一失,脚本从8点59开始执行,成功选上实验或者执行2分钟后退出。


import urllib.request
import http.cookiejar
import urllib.parse
import re
import datetime

postData = {
        'username': '***',
        'pass': '***',
        'password': '***'
        }

url = '***'

cookie = http.cookiejar.CookieJar()
openner = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie))
headers = {
        'User-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
        }
request = urllib.request.Request(url, urllib.parse.urlencode(postData).encode(), headers)
r = openner.open(request)
# print(r.read().decode('UTF-8'))

exUrl = "***"
exPostData = {
        'proSource': '111',
        'proNum': '111',
        'proName': '111',
        'sampleName': '111',
        'sampleCount': '111',
        'sampleDetail': '111',
        'sampleImg': '',
        'dpId': '50',
        'testDate': '2017-04-17',
        'startTime': '14:00:00',
        'endTime': '16:00:00',
        'startTime1': '',
        'endTime1': '',
        'startTime2': '',
        'endTime2': '',
        'remarks': '111',
        'uiid': '1784',
        'diid': '5',
        'parentid': '154',
        'duser': '474',
        'query': '1'
        }
exheaders = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
        'Referer': '***',
        'Origin': '***'
        }

flag = True
noPattern = re.compile("class=\"alert fade in alert-danger\".*?抱歉", re.S)
start = datetime.datetime.now()
end = datetime.datetime.now()
# 如果失败发起多次请求
while flag and (end-start).seconds < 120:
    end = datetime.datetime.now()
    try:
        exRequest = urllib.request.Request(exUrl, urllib.parse.urlencode(exPostData).encode(), exheaders)
        exr = openner.open(exRequest)
        response = exr.read().decode('UTF-8')
        flag = False
        noStr = noPattern.findall(response)
        if noStr:
            print('no')
        else:
            print('yes')
    except urllib.error.URLError as e:
        flag = True
        print(e.code, ':', e.reason)

open('index.html', 'w', encoding='UTF-8').write(response)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值