Python爬虫 (SSL知多少)带你走进Requests(献给人类)丨【生长吧!Python】

举报
ruochen 发表于 2021/07/13 11:01:58 2021/07/13
【摘要】 Python爬虫 (SSL知多少)带你走进Requests(献给人类)
  • SSL

    • SSL证书就是指遵守SSL安全套阶层协议的服务器数字证书(SercureSocketLayer)
    • 美国网景公司开发
    • CA(CertifacateAuthority)是数字证书认证中心,是发送、管理、废除数字证书的受信任的第三方机构
    • 遇到不信任的SSL证书,需要单独处理,案例v17
    # 案例v17
    from urllib import request
    
    # 导入python ssl处理模块
    import ssl
    
    # 利用非认证上下文环境替换认证的上下文环境
    ssl._create_default_https_context = ssl._create_unverified_context
    
    url = "https://www.12306.cn/mormhweb/"
    rsp = request.urlopen(url)
    
    html = rsp.read().decode()
    print(html)
    
    • js加密
    • 有的反爬虫策略采用js对需要传输的数据进行加密处理(通常是md5值)
    • 经过加密,传输的就是密文,但是
    • 加密函数或者过程一定是在浏览器完成,也就是一定会把代码(js代码)暴露给使用者
    • 通过阅读加密算法,就可以模拟出加密过程,从而达到破解
    • 过程查看案例v18, v19
    '''
    案例V18
    破解有道词典
    '''
    
    from urllib import request, parse
    
    def youdao(key):
    
        # url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
        url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
        data = {
            "i": "boy",
            "from": "AUTO",
            "to": "AUTO",
            "smartresult": "dict",
            "client": "fanyideskweb",
            "salt": "15690523207222",
            "sign": "1e28e83873cd4690e108ea28350cd4bb",
            "ts": "1569052320722",
            "bv": "a4f4c82afd8bdba188e568d101be3f53",
            "doctype": "json",
            "version": "2.1"
        }
    
        # 参数data需要时bytes格式
        data = parse.urlencode(data).encode()
    
        headers = {
            "Accept": "application / json, text / javascript, * / *; q = 0.01",
            # "Accept - Encoding": "gzip, deflate",
            "Accept - Language": "zh - CN, zh;q = 0.9",
            "Connection": "keep - alive",
            "Content - Length": "237",
            "Content - Type": "application / x - www - form - urlencoded;charset = UTF - 8",
            "Cookie": "OUTFOX_SEARCH_USER_ID = -1916336379 @ 10.169.0.84;JSESSIONID = aaaF3jqgNCov6fQWqZs1w;OUTFOX_SEARCH_USER_ID_NCOO = 885890211.5426716;___rl__test__cookies = 1569052795328",
            "Host": "fanyi.youdao.com",
            "Origin": "dhttp: // fanyi.youdao.com",
            "Referer": "http: // fanyi.youdao.com/",
            "User - Agent": "Mozilla / 5.0(WindowsNT10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 76.0.3809.132Safari / 537.36",
            "X - Requested - With": "XMLHttpRequest"
        }
    
        req = request.Request(url=url, data=data, headers=headers)
        rsp = request.urlopen(req)
    
        html = rsp.read().decode()
        print(html)
    
    if __name__ == '__main__':
        youdao("boy")
    
                            {"type":"EN2ZH_CN","errorCode":0,"elapsedTime":2,"translateResult":[[{"src":"boy","tgt":"男孩"}]]}
    
    '''
    案例V19
    处理js解密代码
    '''
    
    '''
    通过查找,能找到js代码中操作代码
    
    1. 这个是计算salt的公式  i = "" + (new Date).getTime() + parseInt(10 * Math.random(), 10);
    2. sign: n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj")
    md5一共需要四个参数,第一个和第四个都是固定值的字符串,第三个参数是所谓的salt,
    第二个参数就是输入的要查找的单词
    
    '''
    
    
    def getSalt():
        '''
        salt的公式是: "" + (new Date).getTime() + parseInt(10 * Math.random(), 10);
        把他翻译成python代码
        :return: salt
        '''
        import time, random
    
        salt = int(time.time()*1000) + random.randint(0, 10)
    
        return salt
    
    def getMD5(v):
        '''
    
        :param v:
        :return: sign
        '''
        import hashlib
        md5 = hashlib.md5()
    
        # update需要一个bytes格式的参数
        md5.update(v.encode('utf-8'))
        sign = md5.hexdigest()
    
        return sign
    
    def getSign(key, salt):
    
        sign = "fanyideskweb" + key + str(salt) + "n%A-rKaT5fb[Gy?;N5@Tj"
        sign = getMD5(sign)
    
        return sign
    
    from urllib import request, parse
    
    def youdao(key):
    
        # url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
        url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
    
        salt = getSalt()
    
        data = {
            "i": key,
            "from": "AUTO",
            "to": "AUTO",
            "smartresult": "dict",
            "client": "fanyideskweb",
            "salt": str(salt),
            "sign": getSign(key, salt),
            "ts": "1569052320722",
            "bv": "a4f4c82afd8bdba188e568d101be3f53",
            "doctype": "json",
            "version": "2.1"
        }
    
        # 参数data需要时bytes格式
        data = parse.urlencode(data).encode()
    
        headers = {
            "Accept": "application / json, text / javascript, * / *; q = 0.01",
            # "Accept - Encoding": "gzip, deflate",
            "Accept - Language": "zh - CN, zh;q = 0.9",
            "Connection": "keep - alive",
            "Content - Length": len(data),
            "Content - Type": "application / x - www - form - urlencoded;charset = UTF - 8",
            "Cookie": "OUTFOX_SEARCH_USER_ID = -1916336379 @ 10.169.0.84;JSESSIONID = aaaF3jqgNCov6fQWqZs1w;OUTFOX_SEARCH_USER_ID_NCOO = 885890211.5426716;___rl__test__cookies = 1569052795328",
            "Host": "fanyi.youdao.com",
            "Origin": "dhttp: // fanyi.youdao.com",
            "Referer": "http: // fanyi.youdao.com/",
            "User - Agent": "Mozilla / 5.0(WindowsNT10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 76.0.3809.132Safari / 537.36",
            "X - Requested - With": "XMLHttpRequest"
        }
    
        req = request.Request(url=url, data=data, headers=headers)
        rsp = request.urlopen(req)
    
        html = rsp.read().decode()
        print(html)
    
    if __name__ == '__main__':
        m = input()
        youdao(m)
    
      熊猫
                            {"type":"ZH_CN2EN","errorCode":0,"elapsedTime":2,"translateResult":[[{"src":"熊猫","tgt":"The panda"}]]}
    
  • ajax

    • 异步请求
    • 一定会有url,请求方法,可能有数据
    • 一般使用json格式
    • 案例,爬取豆瓣电影,案例v20
    '''
    案例v20
    爬取豆瓣电影数据
    了解ajax的基本爬取方式
    
    '''
    
    from urllib import request
    import json
    
    url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action=&start=40&limit=20"
    
    rsp = request.urlopen(url)
    data = rsp.read().decode()
    
    data = json.loads(data)
    
    print(data)
    

Requests-献给人类

  • HTTP for Humans,更简洁更友好
  • 继承了urllib的所有特征
  • 底层使用的是urllib3
  • 开源地址:https://github.com/requests/requests
  • 中文文档:http://docs.python-requests.org/zh_CN/latest/index.html
  • 安装:conda install requests
  • get请求
    • requests.get(url)
    • requests.request(“get”, url)
    • 可以带有header和params参数
    • 案例v21
    # 案例v21
    import requests
    
    url = "http://www.baidu.com"
    # 两种请求方式
    # 使用get请求
    rsp = requests.get(url)
    print(rsp.text)
    
    # 使用request请求
    rsp = requests.request("get", url)
    print(rsp.text)
    
  • get返回内容
    • 案例v22
    '''
    案例v22
    使用参数headers和params
    研究返回结果
    
    '''
    import requests
    
    # 完整访问url是下面url加上参数构成
    url = "http://www.baidu.com/s?"
    
    kw = {
        "wd": "大熊猫"
    }
    
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
    }
    
    rsp = requests.get(url, params=kw, headers=headers)
    
    print(rsp.text)
    print(rsp.content)
    print(rsp.url)
    print(rsp.encoding)
    print(rsp.status_code) # 请求返回码
    
  • post
    • rsp = requests.post(url, data=data)
    • 案例v23
    '''
    案例v23
    利用parse模块模拟post请求
    分析百度词典
    分析步骤:
    1. 打开F12
    2. 尝试输入单词girl,发现每次敲一个字母后都有请求
    3. 请求地址是 https://fanyi.baidu.com/sug
    4. 利用 Network-All-Headers 查看,发现FormData的值是 kw:girl
    5. 检查返回内容格式,发现返回的是json格式内容==>需要用到json包
    '''
    
    import requests
    # 负责处理json格式的模块
    import json
    
    '''
    大致流程是:
    1. 利用data构造内容,然后urlopen打开
    2. 返回一个json格式的结果
    3. 结果就应该是girl的释义
    '''
    
    baseurl = 'https://fanyi.baidu.com/sug'
    
    # 存放用来模拟form的数据一定是dict格式
    data = {
        # girl是翻译输入的英文内容,应该是由用户输入,此时使用硬编码
        'kw': 'girl'
    }
    
    # 需要使用parse模块对data进行编码
    print(type(data))
    
    # 我们需要构造一个请求头,请求头部应该至少包含传入的数据的长度
    # request要求传入的请求头是一个dict格式
    
    headers = {
        # 因为使用post请求,至少应该包含content-length 字段
        'Content-Length':str(len(data))
    }
    
    # 有了headers,data,url,就可以尝试发出请求了
    
    rsp = requests.post(baseurl, data=data, headers=headers)
    
    print(rsp.text)
    print(rsp.json())
    
    • data, headers要求dict类型

【生长吧!Python】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/278897

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。