zoukankan      html  css  js  c++  java
  • requests模块

    简介

      使用requests可以模拟浏览器的请求,比起之前用到的urllib,requests模块的api更加便捷(本质就是封装了urllib3)

      requests库发送请求将网页内容下载以后,并不会执行js代码,这需要我们自己分析目标站点然后发起新的request请求

      安装requests:pip3 install requests

      请求方式:常用的就是requests.get()和requests.post()

    import requests
    
    requests.get('https:www.baidu.com')
    requests.post('http://httpbin.org/post',data={'key':'value'})
    requests.put('http://httpbin.org/put',data={'key':'value'})
    requests.delete('http://httpbin.org/delete')
    requests.head('http://httpbin.org/get')
    requests.options('http://httpbin.org/get')

    基于GET请求

    基本请求

    import requests
    response=requests.get('http://baidu.com')
    print(response.text)

    带参数的GET请求---params

    #在请求头内将自己伪装成浏览器
    import requests
    response=requests.get('http://www.baidu.com/s?wd=python&pn=1',
                          headers={
                            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36',
                          })
    print(response.text)
    #如果查询关键字是中文或者有其他特殊符号,则需要先进行url编码
    import requests
    from urllib.parse import urlencode
    # 编码
    wd='python课程'
    encode_res=urlencode({'k':wd},encoding='utf-8')
    keyword=encode_res.split('=')[1]
    #拼接成url
    url='http://www.baidu.com/s?wd=%s&pn=1'%keyword
    response=requests.get(url,
                          headers={
                            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36',
                          })
    res1=response.text
    url编码
    #使用params参数
    import requests
    
    wd='python课程'
    pn=1
    url='http://www.baidu.com/s'
    
    response=requests.get(url,
                          params={
                              'wd':wd,
                              'pn':pn
                          },
                          headers={
                            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36',
                          })
    res2=response.text

    带参数的GET请求---headers

    #通常我们在发送请求时都需要带上请求头,请求头是将自身伪装成浏览器的关键,常见的有用的请求头如下
    Host
    Referer #大型网站通常都会根据该参数判断请求的来源
    User-Agent #客户端
    Cookie #Cookie信息虽然包含在请求头里,但requests模块有单独的参数来处理他,headers={}内就不要放它了
    #添加headers(浏览器会识别请求头,不加可能会被拒绝访问,比如访问https://www.zhihu.com/explore)
    import requests
    response=requests.get('https://www.zhihu.com/explore')
    response.status_code #500
    
    #自己定制headers
    headers={
        'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36',
    
    }
    respone=requests.get('https://www.zhihu.com/explore',
                         headers=headers)
    print(respone.status_code) #200

    带参数的GET请求--cookies

    #登录github,然后从浏览器中获取cookies,以后就可以直接拿着cookie登录了,无需输入用户名密码
    
    import requests
    Cookies={   'user_session':'wGMHFJKgDcmRIVvcA14_Wrt_3xaUyJNsBnPbYzEL6L0bHcfc',
    }
    response=requests.get('https://github.com/settings/emails',
                 cookies=Cookies) #github对请求头没有什么限制,我们无需定制user-agent,对于其他网站可能还需要定制
    print(response.text) 

    基于POST请求

    POST请求和GET请求的差别

    #GET请求
    HTTP默认的请求方法就是GET
         * 没有请求体
         * 数据必须在1K之内!
         * GET请求数据会暴露在浏览器的地址栏中
    
    GET请求常用的操作:
           1. 在浏览器的地址栏中直接给出URL,那么就一定是GET请求
           2. 点击页面上的超链接也一定是GET请求
           3. 提交表单时,表单默认使用GET请求,但可以设置为POST
    
    #POST请求
    (1). 数据不会出现在地址栏中
    (2). 数据的大小没有上限
    (3). 有请求体
    (4). 请求体中如果存在中文,会使用URL编码!
    
    #requests.post()用法与requests.get()完全一致,特殊的是requests.post()有一个data参数,用来存放请求体数据

    发送post请求,模拟浏览器的登录行为

    '''
    一 目标站点分析
        浏览器输入https://github.com/login
        然后输入错误的账号密码,抓包
        发现登录行为是post提交到:https://github.com/session
        而且请求头包含cookie
        而且请求体包含:
            commit:Sign in
            utf8:✓
            authenticity_token:lbI8IJCwGslZS8qJPnof5e7ZkCoSoMn6jmDTsL1r/m06NLyIbw7vCrpwrFAPzHMep3Tmf/TSJVoXWrvDZaVwxQ==
            login:xxxxx
            password:xxx
    
    二 流程分析
        先GET:https://github.com/login拿到初始cookie与authenticity_token
        返回POST:https://github.com/session, 带上初始cookie,带上请求体(authenticity_token,用户名,密码等)
        最后拿到登录cookie
        ps:如果密码时密文形式,则可以先输错账号,输对密码,然后到浏览器中拿到加密后的密码,github的密码是明文
    '''
    
    import requests
    import re
    
    #第一次请求
    r1=requests.get('https://github.com/login')
    r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被授权)
    authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #从页面中拿到CSRF TOKEN
    
    #第二次请求:带着初始cookie和TOKEN发送POST请求给登录页面,带上账号密码
    data={
        'commit':'Sign in',
        'utf8':'',
        'authenticity_token':authenticity_token,
        'login':'xxxxxxxx',
        'password':'xxxx'
    }
    r2=requests.post('https://github.com/session',
                 data=data,
                 cookies=r1_cookie
                 )
    
    login_cookie=r2.cookies.get_dict()
    
    #第三次请求:以后的登录,拿着login_cookie就可以,比如访问一些个人配置
    r3=requests.get('https://github.com/settings/emails',
                    cookies=login_cookie)
    
    print(r3.text) 
    登录github,自己处理cookie信息
    import requests
    import re
    
    session=requests.session()
    #第一次请求
    r1=session.get('https://github.com/login')
    authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #从页面中拿到CSRF TOKEN
    
    #第二次请求
    data={
        'commit':'Sign in',
        'utf8':'',
        'authenticity_token':authenticity_token,
        'login':'xxxxxxxx',
        'password':'xxxx'
    }
    r2=session.post('https://github.com/session',
                 data=data,
                 )
    
    #第三次请求
    r3=session.get('https://github.com/settings/emails')
    print(r3.text) 
    登录github,使用session
    requests.post(url='xxxxxxxx',
                  data={'xxx':'yyy'}) #没有指定请求头,#默认的请求头:application/x-www-form-urlencoed
    
    #如果我们自定义请求头是application/json,并且用data传值, 则服务端取不到值
    requests.post(url='',
                  data={'':1,},
                  headers={
                      'content-type':'application/json'
                  })
    
    
    requests.post(url='',
                  json={'':1,},
                  ) #默认的请求头:application/json

    响应response

    response属性

    import requests
    respone=requests.get('http://www.jianshu.com')
    # respone属性
    print(respone.text)
    print(respone.content)
    print(respone.status_code)
    print(respone.headers)
    print(respone.cookies)
    print(respone.cookies.get_dict())
    print(respone.cookies.items())
    print(respone.url)
    print(respone.history)
    print(respone.encoding)
    
    #关闭:response.close()
    from contextlib import closing
    with closing(requests.get('xxx',stream=True)) as response:
        for line in response.iter_content():
        pass

    编码

    import requests
    response=requests.get('http://www.autohome.com/news')
    # response.encoding='gbk' #汽车之家网站返回的页面内容为gb2312编码的,而requests的默认编码为ISO-8859-1,如果不设置成gbk则中文乱码
    print(response.text)

    二进制数据处理

    import requests
    response=requests.get('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1509868306530&di=712e4ef3ab258b36e9f4b48e85a81c9d&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F11385343fbf2b211e1fb58a1c08065380dd78e0c.jpg')
    
    with open('a.jpg','wb') as f:
        f.write(response.content)
    #stream参数:一点一点的取,比如下载视频时,如果视频100G,用response.content然后一下子写到文件中是不合理的
    
    import requests
    
    response=requests.get('https://gss3.baidu.com/6LZ0ej3k1Qd3ote6lo7D0j9wehsv/tieba-smallvideo-transcode/1767502_56ec685f9c7ec542eeaf6eac93a65dc7_6fe25cd1347c_3.mp4',
                          stream=True)
    
    with open('b.mp4','wb') as f:
        for line in response.iter_content():
            f.write(line)

    解析json

    import requests
    response=requests.get('http://httpbin.org/get')
    
    import json
    res1=json.loads(response.text) #太麻烦
    
    res2=response.json() #直接获取json数据
    
    print(res1 == res2) #True

    Redirection and History

    import requests
    import re
    
    #第一次请求
    r1=requests.get('https://github.com/login')
    r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被授权)
    authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #从页面中拿到CSRF TOKEN
    
    #第二次请求:带着初始cookie和TOKEN发送POST请求给登录页面,带上账号密码
    data={
        'commit':'Sign in',
        'utf8':'',
        'authenticity_token':authenticity_token,
        'login':'xxxxxxx',
        'password':'xxxx'
    }
    
    #测试一:没有指定allow_redirects=False,则响应头中出现Location就跳转到新页面,r2代表新页面的response
    r2=requests.post('https://github.com/session',
                 data=data,
                 cookies=r1_cookie
                 )
    
    print(r2.status_code) #200
    print(r2.url) #看到的是跳转后的页面
    print(r2.history) #看到的是跳转前的response
    print(r2.history[0].text) #看到的是跳转前的response.text
    
    
    #测试二:指定allow_redirects=False,则响应头中即便出现Location也不会跳转到新页面,r2代表的仍然是老页面的response
    r2=requests.post('https://github.com/session',
                 data=data,
                 cookies=r1_cookie,
                 allow_redirects=False
                 )
    
    print(r2.status_code) #302
    print(r2.url) #看到的是跳转前的页面https://github.com/session
    print(r2.history) #[]
  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    108. Convert Sorted Array to Binary Search Tree
    111. Minimum Depth of Binary Tree
    49. Group Anagrams
    使用MALTAB标定实践记录
    442. Find All Duplicates in an Array
    522. Longest Uncommon Subsequence II
    354. Russian Doll Envelopes
    opencv 小任务3 灰度直方图
    opencv 小任务2 灰度
  • 原文地址:https://www.cnblogs.com/iamluoli/p/9254870.html
Copyright © 2011-2022 走看看