01、https http复习

--HTTP:超文本传输协议,默认端口号是80 
    --超文本:是指超过文本,不仅限于文本;还包括图片、音频、视频等文件 
    --传输协议:是指使用共用约定的固定格式来传递转换成字符串的超文本内容 
--HTTPS:HTTP + SSL(安全套接字层),即带有安全套接字层的超本文传输协,默认端口号:443 
    --SSL对传输的内容(超文本,也就是请求体或响应体)进行加密 
    --可以打开浏览器访问一个url,右键检查,点击net work,点选一个url,查看http协议的形式

02、常见的请求头  和  响应头

--常见请求头
    Content-Type
    Host (主机和端口号)  域名
    Connection (链接类型)  Keep-Alive
    Upgrade-Insecure-Requests (升级为HTTPS请求)  1 表示自动将 http 升级为 https
    User-Agent (浏览器名称)  用户代理,携带系统和浏览器信息
    Referer (页面跳转处)  从哪个页面来的[来源网页地址],可用于爬虫识别,同时可防止盗链
    Cookie (Cookie)  状态保持,查看是否登录[有时效性],判断是否为某一个用户
    Authorization(用于表示HTTP协议中需要认证资源的认证信息,如前边web课程中用于jwt认证) 一般不出现
    

--响应头
    Set-Cookie (对方服务器设置cookie到用户浏览器的缓存)  服务器返回给前端保持对话的cookie信息保存的地方,后来发请求的时候都需要带上这个

03、常见状态码

200:成功

302:跳转,新的url在响应的Location头中给出
303:浏览器对于POST的响应进行重定向至新的url
307:浏览器对于GET的响应重定向至新的url

403:资源不可用;服务器理解客户的请求,但拒绝处理它(没有权限)
404:找不到该页面
405:问题:http post请求网页会出现405
     原因:Apache、IIS、Nginx等绝大多数web服务器,都不允许静态文件响应POST请求
     解决:将post请求改为get请求

500:服务器内部错误
503:服务器由于维护或者负载过重未能应答,在响应中可能可能会携带Retry-After响应头;有可能是因为爬虫频繁访问url,使服务器忽视爬虫的请求,最终返回503响应状态码

--所有状态码都不可行,前端主要还是看console 和 response,后端主要还是看日志和报错

3、request模块  --  发送一个get 请求,获取响应源码

--requests文档:中文 主要是发送请求,获取响应数据
    https://requests.readthedocs.io/zh_CN/latest/

--requests 发出一个 get 请求,返回响应html文件
    import requests

    url_bd = 'http://www.baidu.com'
    url_request = requests.get(url_bd)
    
    # 打印 响应的源码
    print(url_request.text)  # str类型数据

4、requests模块  --  发送一个 get 请求,获取响应体response

response.text 和response.content的区别:
    response.text
        类型:str
        解码类型: requests模块自动根据HTTP 头部对响应的编码作出有根据的推测,推测的文本编码
    response.content
        类型:bytes,因为是二进制所以需要解码
        解码类型: 没有指定

--text手动解码:
    import requests

    url_bd = 'http://www.baidu.com'
    url_request = requests.get(url_bd)   
 
    url_request.encoding = 'utf8'  # 设置解码规则为 utf8,否则默认编码格式 ISO-8859-1
    print(url_request.encoding)
    print(url_request.text)
    print(url_request.encoding)

--content自动调用函数解码
    import requests

    url_bd = 'http://www.baidu.com'
    url_request = requests.get(url_bd)

    print(url_request.content)
    print(url_request.content.decode())  # 默认utf8解码

5、response的其他响应内容

response = requests.get(url)中response是发送请求获取的响应对象;response响应对象中除了text、content获取响应内容以外还有其它常用的属性或方法:
    --response.url响应的url;有时候响应的url和请求的url并不一致
    --response.status_code 响应状态码
    --response.request.headers 响应对应的请求头
    --response.headers 响应头
    --response.request._cookies 响应对应请求的cookie;返回cookieJar类型
    --response.cookies 响应的cookie(经过了set-cookie动作;返回cookieJar类型
    --response.json()自动将json字符串类型的响应内容转换为python对象(dict or list)

--示例代码如下:
    import requests

    url_bd = 'http://www.baidu.com'
    url_request = requests.get(url_bd)

    # 响应地址
    print(url_request.url)
    # http://www.baidu.com/

    # 响应状态码
    print(url_request.status_code)
    # 200

    # 响应的请求头,这请求头结果是python-requests/2.24.0,表示是从python模块发起的请求
    print(url_request.request.headers)
    # {'User-Agent': 'python-requests/2.24.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}

    # 响应头
    print(url_request.headers)
    # {'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Wed, 26 Aug 2020 13:25:06 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:27:36 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'}

    # 打印响应中携带的cookies
    print(url_request.cookies)
    # <RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>

6、发送带headers的请求

--记住:如果单纯只有一个url的话,所获得的content || text是不完整的,因此需要加上各种请求头
--network中的 preserve log 勾选的话表示每次f5刷新界面以后不清楚原有内容

--response = requests.get(url, headers={})  请求头 headers 是个字典

--代码示例:
    import requests

    url_bd = 'http://www.baidu.com'

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36',
    
    }

    url_request = requests.get(url_bd, headers=headers)

    print(url_request.content.decode())

7、发送带参数 和 headers的请求

--带参数 和 请求头的url请求基本格式如下:
    kw = {}  # 和 headers 一样,params也是一个字典
    response = requests.get(url, headers=headers, params=kw)

--代码示例:
    import requests

    url_bd = 'http://www.baidu.com/s'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36'
    }

    params = {'wd': 'python'}

    url_request = requests.get(url_bd, headers=headers, params=params)
    print(url_request.content.decode())

8、headers中包含Cookies 来进行请求

--网站经常利用请求头中的Cookie字段来做用户访问状态的保持,那么我们可以在headers参数中添加Cookie,模拟普通用户的请求。

--通过比较登陆以及不登陆之间网页显示的区别,可以验证所携带的Cookie是否有效

--比如下面 百度 登陆以后有你的帐号名字在html文件中就可以用来验证

--示例代码如下:
    import requests

    url_bd = 'https://www.baidu.com'  # 这里是 https 不是 http不要弄错了
    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36',
    'Cookie': 'BIDUPSID=2CF813A2AEB265C63047C561C2F527A5; PSTM=1598334227; BAIDUID=2CF813A2AEB265C69E357779E7CB081F:FG=1; BD_UPN=12314753; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; BD_CK_SAM=1; PSINO=5; H_PS_645EC=6e6aIC2q4odoi7mcnGGdS65lfidJ7TlEwI1A%2FEKA%2BoJKieFj9J72m6qELsU; COOKIE_SESSION=1773_0_1_3_0_3_0_1_0_1_2_2_0_0_0_0_0_0_1598454900%7C3%230_0_1598454900%7C1; BD_HOME=1; sug=3; sugstore=1; ORIGIN=0; bdime=0; H_PS_PSSID=32645_1435_32619_32537_32327_32351_32046_32681_32116_31709_32618_32583; BDUSS=ZVU0tLSnZoTU02dUttTDVBc2NyTGEzZno1bmFHaXpmSnJELVpPSzVDTnlFRzVmSVFBQUFBJCQAAAAAAAAAAAEAAAA7QlE-1MLA1tTE1MNMTExMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHKDRl9yg0Zfa0; BDUSS_BFESS=ZVU0tLSnZoTU02dUttTDVBc2NyTGEzZno1bmFHaXpmSnJELVpPSzVDTnlFRzVmSVFBQUFBJCQAAAAAAAAAAAEAAAA7QlE-1MLA1tTE1MNMTExMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHKDRl9yg0Zfa0'
    }

    url_request = requests.get(url_bd, headers=headers)
    print(url_request.content.decode())

    with open('cookie_baidu_login.txt', 'w', encoding='utf8') as f:
        f.write(url_request.content.decode())

9、使用Cookies 参数来保持对话:这里的Cookie的意思不是指headers字典中的一组键值,而是requests.get()中的一个参数,例如 requests.get(headers=headers_dict, cookies=cookies_dict), cookies 和 headers平级

--这个其实就是一个切割字符串,生成字典的表达形式

--涉及到:字典生成表达式
--建议:面试的时候使用字典表达式等一系列复杂表达,但是自己写代码简洁易规范最好,而且简洁不是片面追求代码量少,而是使用尽可能少的逻辑 内存占用 cpu占用 完成规定的功能,再次强调不是代码少就好,所以不要觉得推导式非常高级,容易引起阅读困难等问题

--示例代码如下:
    import requests

    url_bd = 'https://www.baidu.com'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36'
    }

    Cookies = 'BIDUPSID=2CF813A2AEB265C63047C561C2F527A5; PSTM=1598334227; BAIDUID=2CF813A2AEB265C69E357779E7CB081F:FG=1; BD_UPN=12314753; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; BD_CK_SAM=1; PSINO=5; H_PS_645EC=6e6aIC2q4odoi7mcnGGdS65lfidJ7TlEwI1A%2FEKA%2BoJKieFj9J72m6qELsU; COOKIE_SESSION=1773_0_1_3_0_3_0_1_0_1_2_2_0_0_0_0_0_0_1598454900%7C3%230_0_1598454900%7C1; BD_HOME=1; sug=3; sugstore=1; ORIGIN=0; bdime=0; H_PS_PSSID=32645_1435_32619_32537_32327_32351_32046_32681_32116_31709_32618_32583; BDUSS=ZVU0tLSnZoTU02dUttTDVBc2NyTGEzZno1bmFHaXpmSnJELVpPSzVDTnlFRzVmSVFBQUFBJCQAAAAAAAAAAAEAAAA7QlE-1MLA1tTE1MNMTExMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHKDRl9yg0Zfa0; BDUSS_BFESS=ZVU0tLSnZoTU02dUttTDVBc2NyTGEzZno1bmFHaXpmSnJELVpPSzVDTnlFRzVmSVFBQUFBJCQAAAAAAAAAAAEAAAA7QlE-1MLA1tTE1MNMTExMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHKDRl9yg0Zfa0'

    Cookies_dict = {cookie.split('=')[0]:cookie.split('=')[1] for cookie in         Cookies.split(';')}

    url_request = requests.get(url_bd, headers=headers, cookies=Cookies_dict)
    print(url_request.content.decode())

    with open('cookie_baidu_login.txt', 'w', encoding='utf8') as f:
        f.write(url_request.content.decode())

10、timeout参数

--在平时网上冲浪的过程中,我们经常会遇到网络波动,这个时候,一个请求等了很久可能任然没有结果。

--在爬虫中,一个请求很久没有结果,就会让整个项目的效率变得非常低,这个时候我们就需要对请求进行强制要求,让他必须在特定的时间内返回结果,否则就报错。

--超时参数timeout的使用方法
    response = requests.get(url, timeout=3)
    timeout=3表示:发送请求后,3秒钟内返回响应,否则就抛出异常

--代码示例:
    import requests

    url = 'https://twitter.com'

    response = requests.get(url, timeout=3)
    print(response.text)