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

       一、requests模块介绍  

    #介绍:使用requests可以模拟浏览器的请求,比起之前用到的urllib,requests模块的api更加便捷(本质就是封装了urllib3)
    
    #注意:requests库发送请求将网页内容下载下来以后,并不会执行js代码,这需要我们自己分析目标站点然后发起新的request请求
    
    #安装:pip3 install requests
    
    #各种请求方式:常用的就是requests.get()和requests.post()
    >>> import requests
    >>> r = requests.get('https://api.github.com/events')
    >>> r = requests.post('http://httpbin.org/post', data = {'key':'value'})
    >>> r = requests.put('http://httpbin.org/put', data = {'key':'value'})
    >>> r = requests.delete('http://httpbin.org/delete')
    >>> r = requests.head('http://httpbin.org/get')
    >>> r = requests.options('http://httpbin.org/get')
    
    #建议在正式学习requests前,先熟悉下HTTP协议
    http://www.cnblogs.com/linhaifeng/p/6266327.html

     二、基于GET请求

    1.基本请求

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

    2、带参数的GET请求->params

    #在请求头内将自己伪装成浏览器,否则百度不会正常返回页面内容
    import requests
    response=requests.get('https://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编码
    from urllib.parse import urlencode
    wd='egon老师'
    encode_res=urlencode({'k':wd},encoding='utf-8')
    keyword=encode_res.split('=')[1]
    print(keyword)
    # 然后拼接成url
    url='https://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
    
    自己拼接GET参数
    自己拼接GET参数
    #上述操作可以用requests模块的一个params参数搞定,本质还是调用urlencode
    from urllib.parse import urlencode
    wd='egon老师'
    pn=1
    
    response=requests.get('https://www.baidu.com/s',
                          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
    
    #验证结果,打开a.html与b.html页面内容一样
    with open('a.html','w',encoding='utf-8') as f:
        f.write(res1) 
    with open('b.html', 'w', encoding='utf-8') as f:
        f.write(res2)
    
    params参数的使用
    params参数的使用

    3、带参数的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

    4、带参数的GET请求->cookies

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

    三、基于POST请求

    1.介绍

    #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参数,用来存放请求体数据

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

    注:对于登录来说,应该输错用户名或密码然后分析抓包流程,用脑子想一想,输对了浏览器就跳转了,还分析个毛线,累死你也找不到包
    '''
    一 目标站点分析
        浏览器输入https://github.com/login
        然后输入错误的账号密码,抓包
        发现登录行为是post提交到:https://github.com/session
        而且请求头包含cookie
        而且请求体包含:
            commit:Sign in
            utf8:✓
            authenticity_token:lbI8IJCwGslZS8qJPnof5e7ZkCoSoMn6jmDTsL1r/m06NLyIbw7vCrpwrFAPzHMep3Tmf/TSJVoXWrvDZaVwxQ==
            login:egonlin
            password:123
    
    
    二 流程分析
        先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':'317828332@qq.com',
        'password':'alex3714'
    }
    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('317828332@qq.com' in r3.text) #True
    
    自动登录github(自己处理cookie信息)
    自动登录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':'317828332@qq.com',
        'password':'alex3714'
    }
    r2=session.post('https://github.com/session',
                 data=data,
                 )
    
    #第三次请求
    r3=session.get('https://github.com/settings/emails')
    
    print('317828332@qq.com' in r3.text) #True
    
    requests.session()自动帮我们保存cookie信息
    requests.session()自动帮我们保存cookie信息

    注意:

    re.compile() 可以把正则表达式编译成一个正则表达式对象.

    re.findall() 方法读取html 中包含 imgre(正则表达式)的数据。

    r.text和r.content的区别是什么呢?

    r.text是unicode编码的响应内容(r.text is the content of the response in unicode),
    r.content是字符编码的响应内容(r.content is the content of the response in bytes);
    text属性会尝试按照encoding属性自动将响应的内容进行转码后返回,如果encoding为None,requests会按照chardet(这是什么?)猜测正确的编码;如果你想取文本,可以通过r.text, 如果想取图片,文件,则可以通过r.content(这点我现在也不是很明白).针对响应内容是二进制文件(如图片)的场景,content属性获取响应的原始内容(以字节为单位)

    示例:登录github

    import requests
    import re
    #第一次请求
        # GET请求
        # 请求头
        #    - 获取token和
        #    - User-agent
        #    - cookie
    # 第二次请求
        #POST请求
        #请求头
            # referer
            # User-agent
        #请求体
            #获取data
    # 第三次请求,登录成功之后
        #- 请求之前自己先登录一下,看一下有没有referer
        #- 请求新的url,进行其他操作
        #- 查看用户名在不在里面
    #第一次请求
    response1 = requests.get(
        "https://github.com/login",
        headers = {
            "User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36",
        },
    )
    authenticity_token = re.findall('name="authenticity_token".*?value="(.*?)"',response1.text,re.S)
    r1_cookies =  response1.cookies.get_dict()
    # print(r1_cookies,"cookie")  #获取到的cookie
    
    #第二次请求
    response2 = requests.post(
        "https://github.com/session",
        headers = {
            "Referer": "https://github.com/",
            "User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36",
        },
        data={
                "commit":"Sign in",
                "utf8":"",
                "authenticity_token":authenticity_token,
                "login":"oridn",
                "password":"xxxx",
    zhy..azjash1234
        },
        cookies = r1_cookies
    )
    print(response2.status_code)
    print(response2.history)  #跳转的历史状态码
    
    #第三次请求,登录成功之后,访问其他页面
    r2_cookies = response2.cookies.get_dict()  #拿上cookie,知道是你登录了,就开始访问页面
    response3 = requests.get(
        "https://github.com/settings/emails",
        headers = {
            "Referer": "https://github.com/",
            "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36",
        },
        cookies = r2_cookies,
    )
    print(response3.text)
    print("oridn" in response3.text)   #True返回True说明就成功了

    3.补充

    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 
  • 相关阅读:
    git中文输入显示问题
    how to write a DLL/SO in C/C++ for Python
    python,ctypes
    vc++,dll,lib文件百科
    c++ singleton
    build python on windows
    web前端后端
    动态链接库*.so的编译与使用
    qt,ui,QUiLoader
    qt,script
  • 原文地址:https://www.cnblogs.com/moning/p/8295679.html
Copyright © 2011-2022 走看看