Python爬虫(3)

Requests库的操作。

(可以用命令行直接进行敲也行的,或者用各种编译器)

高级操作

1.文件上传(导包)


import requests

files = {'file' : open('logo.gif','rb')}
resp = requests.post('http://httpbin.org/post', files=files)
print(resp.text)

文件上传的操作只要我们从文件夹中把文件读取出来,并且赋值给 files 参数,就可以了,打印出源代码我们就可以看待上传文件的字节流了。

2.获取Cookie


>>>import requests

>>>resp = requests.get('http://www.baidu.com')
>>>print(resp.cookies)
<RequestsCookieJar[]>
>>>for key, value in resp.cookies.items():
...    print(key + '=' + value)
BDORZ=27315

我们可以通过获取字典的键值对来查看cookie.

3.会话维持

我们获得到了cookie就可以做一个会话维持,可以维持一个登录的状态,也就是做模拟登录。我们来看实现方式:

import requests

s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123456789') # 设置了一个cookie
resp = s.get('http://httpbin.org/cookies')
print(resp.text)

>>>import requests

>>>resp = requests.get('http://www.baidu.com')
>>>print(resp.cookies)
<RequestsCookieJar[]>
>>>for key, value in resp.cookies.items():
...    print(key + '=' + value)
BDORZ=27315

这就相当于模拟了一个会话,比如做登陆验证,可以用session,POST 一下,登陆一下,然后保持会话信息,在访问登录过页面的话,就可以正常获取登录后的页面了。如果你要模拟登录,可以通过申明Session对象,再用Session对象发起两次get请求,那么这两次请求相当于在一个浏览器里面,先访问set cookie页面,在访问get cookie页面。当然,cookie是自动处理的,不需要担心写一些处理cookies的方法。

建议模拟登录用requestsSession对象。

4.SSL证书验证

Requests可以为 HTTPS 请求验证 SSL 证书,就像 web浏览器一样。要想检查某个主机的 SSL证书,你可以使用 verify参数:

>>>import requests

>>>requests.get('https://kennethreitz.com', verify=True) # verify参数默认值为True
requests.exceptions.SSLError: hostname 'kennethreitz.com' doesn't match either of '*.herokuapp.com', 'herokuapp.com'

如果不想他报这个错误,我们可以把参数verify的值设为False.运行后发现程序没有报错,但是会出现警告信息,警告我们要验证 SSL证书。如果要消除这个警告,我们需要调用原生包:


>>>import requests
>>>from requests.packages import urllib3

urllib3.disable_warnings()
>>>requests.get('https://kennethreitz.com', verify=False)

我们还可以自己指定一个证书:

>>>import requests

>>>resp = requests.get('https://kennethreitz.com', cert=('/path/server.crt', '/path/key'))
>>>print(resp.status_code)
200

5.代理设置

有些网站会限制 IP 访问频率,超过频率就断开连接。这个时候我们就需要使用到代理,我们可以通过为任意请求方式提供proxies参数来配置单个请求。


import requests

proxies = {
    "http": "http://10.10.1.10:3128",
    "https": "http://10.10.1.10:1080",
}
resp = requests.get('http://www.baidu.com', proxies=proxies)
print(resp.status_code)

也可以通过环境变量 HTTP_PROXY 和 HTTPS_PROXY 来配置代理。
有些代理需要加上用户名和密码的,代理可以使用http://user:password@host/语法,比如:


proxies = {
    "http": "http://user:pass@10.10.1.10:3128/",
}

除了基本的 HTTP代理,Requests还支持SOCKS协议的代理,如果需要用的,可以安装带三方库:

$ pip install requests[socks]

安装好依赖以后,使用 SOCKS 代理和使用 HTTP 代理一样简单:

proxies = {
    "http": 'socks5://user:pass@host:port',
    "https": 'socks5://user:pass@host:port'
}

6.超时设置

超时设置就是设置请求的时间,如果在规定的时间内没有返回应答,就抛出异常.

import requests

resp = requests.get('http://www.baidu.com', timeout=0.5)
print(resp.status_code)

如果在0.5秒内没有返回,就会报出ReadTimeout的异常。
如果远端服务器很慢,你可以让Request永远等待,传入一个None作为timeout值,然后就冲咖啡去吧。

7.认证设置

有一些网站在访问的时候需要我们输入用户名和密码,那么这种网站我们要怎样处理呢。


import requests
from requests.auth import HTTPBasicAuth

resp = requests.get(url, auth=HTTPBasicAuth('username','password'))
print(resp.status_code)

 

调用HTTPBasicAuth类,直接传入用户名和密码就可以了。

8.异常处理

如果你遇到无法访问的网站,或者是你的网速不够快,你的访问超时,就会导致程序的中断。显然我们在实际的抓取中不愿意看到爬取到一半的程序突然中断的情况,那么我们能够避免这种程序中断的情况吗,答案是肯定的:

import requests
from requests.exceptions import ReadTimeout, ConnectionError, RequestException

try:
    resp = requests.get('http://httpbin.org/get', timeout=0.5)
    print(resp.status_code)
except ReadTimeout: # 访问超时的错误
    print('Timeout')
except ConnectionError: # 网络中断连接错误
    print('Connect error')
except RequestException: # 父类错误
    print('Error')

这样我们就可以把requests抓取过程中常见的异常都处理捕获了,捕获错误应该先捕获子类异常在捕获父类异常,这样做能够更加直观清楚的应对程序中出现的错误了。

如果我们能够自己捕获了这些异常,就可以保证我们的爬虫一直运行了。

 

12306数据爬取实验:

"""
实验步骤:
    1.请求12306的验证码,先获取验证码的请求地址url
    2.手动校验验证码(要先先将验证码下载到本地)————电脑配置64位
    3.获取用户登录的请求(三个验证请求)
    4.自动校验验证码
    5.对我们的数据进行模拟登陆
    6.将原有的手动验证码登陆替换为自动验证码登陆(完整自动登陆的实现)

"""
import requests
import json
import sys
import base64
import time
from  urllib import parse
import matplotlib
class Spider:
    def __init__(self):
        """
        这个方法等同于Java的构造方法,
        其主要的作用就是对一部分的参数进行初始化,
        self的效果和Java的this主要是一些参数需要在全局范围内使用

        """
        #因为后面有很多的请求是需要记录上一次访问的信息的,所以为了保证多个页面的请求能够记录上一次的操作
        self.session = requests.Session()
        #伪造模拟的headers
        self.headers={
            "User-Agent": "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; The World)"
        }
        #产生验证码请求的URL
        self.captcha_url = "https://kyfw.12306.cn/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand&1558425404464&callback=jQuery19109890480995451634_1558425385680&_=1558425385681"

        #校验验证码请求的url
        self.captcha_url
    """
        将一个非标准的json字符串,解析成真正的json(12306大部分请求都可以用)
          一个解决12306json格式的通用方法
    """
    def json_cutting(self,res):
        #将一个非标准的json字符串切割成一个标准的json字符串
        data = res.text.split("(")[1][:-2]
        #切割完毕后将字符串转成python的数据类型(json类型)
        data = json.loads(data) #将json转成字典
        return data




    """
        下载验证码函数,即下载basic64(python自带的库)编码格式的图片函数
        filename:下载图片后锁保存的名字
        content:图片basic64的内容
    """
    def download_captcha(self):
        #请求获取验证码的地址
        res = self.session.get(self.captcha_url,headers = self.headers)
        #print(res.text)获取图片json
        data = self.json_cutting(res)
        if data.get("result_code") == "0":
            print("验证码:{}".format(data.get("result_message")))
            #获取base64编码的图片
            image = data.get("image")
            #调用图片下载的函数
            self.download_base64_picture("captcha.jpg",image)
            #设置一个休眠,单位秒
            time.sleep(1)
            print(image)
        else:
            print("验证码:{}".format(data.get("result_message")))
            #失败则退出程序
            sys.exit(1)
        pass

    """手动校验验证码的函数"""
    def check_captcha(self):
        result = parse.urlparse(self.captcha_url)
        call_back = parse.parse_qs(result.query).get("callback")[0]
        #print(call_back)callback\
        #字典
        patload = {
            "call_back":call_back,
            "aswner":input("请输入您验证码的坐标轴:")
            "rand":"sjrand",
            "login_site":"E",
            "_":"1558440787842"
        }
        s = self.session.get(self.captcha_check,params = patload)
        data = self.json_cutting(s)
        if data.get("result_code") == "4":
            print(data.get("result_message"))
        else:
            print(data.get("result_message"))
            #强制退出

            sys.exit(1)
        pass


    def download_base64_picture(self,filename,content):
        image = base64.b64decode(content)
        file = open(filename,"wb") #以字节的方式写入到本地
        file.write(image)
        file.close()

    def run(self):
        self.download_captcha()
        self.check_captcha()

if __name__ == '__main__':
    s = Spider()
    s.run()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值