zoukankan      html  css  js  c++  java
  • 爬虫之requests模块的使用

    一、Ruquest模块基础

    requests模块可以模拟浏览器发送多种请求方式

    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')
    

    二、基于GET请求

    1.基本请求

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

    2.带参数的GET请求(params、headers)

    import requests
    # 请求方式
    kwords = input('请输入关键字:>>>').strip()
      # 使用urlencode可以解析中文
    url = "https://www.baidu.com/s?"
    params = {'wd': kwords}
    # 请求头
    baidu_headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36 chrome-extension",
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
    }
    # 发送请求
    response = requests.get(url,
                            params=params,
                            headers=baidu_headers,
                            )
    print(response.status_code)  # 响应状态码
    # print(response.text)   # 返回的html
    
    # 保存数据
    with open('search1.html', 'w', encoding='utf-8') as f:
        f.write(response.text)
        print('保存成功')
    

    3.带参数的GET请求(cookies)

    # 基于get请求携带参数cookies, 以访问GitHub邮箱示范
    
    import requests
    
    url = 'https://github.com/settings/emails'
    cookies = {'user_session':"Osrktx19GnRnCYy0eVgixmEc637QGQDaZ7Upi30RI6uG-WWk"}
    response = requests.get(url,cookies=cookies)  #github对请求头没有什么限制,我们无需定制user-agent,对于其他网站可能还需要定制
    print("928990486@qq.com" in response.text)  # True
    

    三、基于POST请求

    1.get请求与post请求的区别

    #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请求,模拟浏览器的登录行为

    注意:

    ​  1、对于登录来说,应该输错用户名或密码然后分析抓包流程,如果输对了浏览器就跳转了,就没法分析了,抓不到包了,
    ​ 2、要做登录的时候一定记得要把cookie先清除;
      3、requests.session():中间的cookie都不用自己分析了,有用的没用的都给放进来了、
      4、response.cookie.get_dict() #获取cookie

    '''
    一 目标站点分析
        浏览器输入https://github.com/login
        然后输入错误的账号密码,抓包
        发现登录行为是post提交到:https://github.com/session
        而且请求头包含cookie
        而且请求体(form data)包含:
     		commit: Sign in
    		utf8: ✓
    		authenticity_token: NG74Lb4wcJn/emTlJS/A71Wk2WJioAwqgelWqBvPoqe0aD8tWsn8r+088bFUCOv7FY+MI9JmOy+ojP3pisz35w==ga_id: 804200945.1577712060
    		login: 928990486@qq.com
    		password: 123456
    		webauthn-support: supported
    		webauthn-iuvpaa-support: unsupported
    		required_field_55c0:
    		timestamp: 1577713659056
    		timestamp_secret: 65a511d2fd997e58b721ba390196372e6beb012c12a69d57156c9a2b20c267ea
    
    
    二 流程分析
        先GET:https://github.com/login拿到初始cookie与authenticity_token与timestamp_secret随机加密字符串
        返回POST:https://github.com/session, 带上初始cookie,带上请求体(authenticity_token,用户名,密码等)
        最后拿到登录cookie
    
        ps:如果密码是密文形式,则可以先输错账号,输对密码,然后到浏览器中拿到加密后的密码,github的密码是明文
    '''
    
    import requests
    import re
    
    
    # 第一次请求
    login_headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36 chrome-extension",
    }
    
    r1 = requests.get('https://github.com/login',headers=login_headers)
    
    # 2)先解析获取authenticity_token与timestamp_secret, 通过re模块实现
    authenticity_token=re.findall(r'<input type="hidden" name="authenticity_token" value="(.*?)" />',
    							  r1.text,
    							  re.S)[0]   # re.S 代表全文检索
    timestamp_secret = re.findall('<input type="hidden" name="timestamp_secret" value="(.*?)" class="form-control" />',
                                  r1.text,
                                  re.S)[0]
    print(authenticity_token)
    
    
    # 第二次请求:带着初始cookie和TOKEN发送POST请求给登录页面,带上账号密码通过post请求访问https://github.com/session
    form_data = {
     		'commit': 'Sign in',
    		'utf8': '✓',
    		'authenticity_token':authenticity_token,
    		'login': '928990486@qq.com',
    		'password': 'qq7855993',
    		'webauthn-support': 'supported',
    		'webauthn-iuvpaa-support': 'unsupported',
    		'required_field_55c0':'',
    		'timestamp': 1577717454909,
    		'timestamp_secret': timestamp_secret
    
    }
    
    r2 = requests.post('https://github.com/session',
                       data=form_data,
                       cookies=r1.cookies,
                       )
    login_cookie = r2.cookies
    
    
    
    #第三次请求:以后的登录,拿着login_cookie就可以,比如访问一些个人配置
    r4=requests.get('https://github.com/settings/emails',
                    cookies=login_cookie
                    )
    
    
    print('928990486@qq.com' in r4.text) #True
    

    四、Response属性

    import requests
    
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
    }
    
    response = requests.get('https://www.jianshu.com', headers=headers)
    
    '''
    # response属性:
    '''
    # 1.响应状态码(*******)
    print(response.status_code)
    
    # 2.响应文本(html文本)(*******)
    # print(response.text)
    
    # 3.响应的cookies(*******)  注意: 有些网站可以直接传入cookies=cookies对象,有些需要先转换成dict类型
    print(type(response.cookies))
    
    # 4.将cookies对象转成dict类型
    print(type(response.cookies.get_dict()))
    # 5.将cookies对象转成list类型
    print(type(response.cookies.items()))
    
    
    response = requests.get('https://www.baidu.com', headers=headers)
    # 有些网站的默认编码不是utf-8,会出现中文错乱
    # print(response.text)
    # 5.响应编码格式(*******)
    print(response.encoding)  # ISO-8859-1
    # 解决字符编码不对应导致的数据展示错乱问题
    response.encoding = 'utf-8'
    print(response.encoding)  # utf-8
    # print(response.text)
    
    
    # 6.返回的二进制数据(*******)
    # 一般用于爬取图片、视频、音频
    print(response.content)
    
    # 7.获取当前网站的url地址
    print(response.url)
    
    
    
    # 8.获取网站返回的json数据
    # print(response.json())
    import json
    
    response = requests.get('https://landing.toutiao.com/api/pc/realtime_news/')
    print(response.status_code)
    # print(response.text)
    print(json.loads(response.text))  # 解析json数据的第一种方式
    print(response.json())   # 解析json数据的第二种方式
    
    
    # 9.获取图片二进制流数据,并且保存到本地
    response = requests.get('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1577801361635&di=d9fb985650a3fbf2702cf1345fd45a3a&imgtype=0&src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F8709968837%2F640')
    print(response.status_code)
    
    # 注意: 二进制数据有可能会很大
    print(response.content)
    
    # 10. iter_content: 将二进制数据装进一个迭代器中
    with open('靓仔.jpg', 'wb') as f:
        # f.write(response.content)
        # iter_content: 将二进制数据装进一个迭代器中
        for line in response.iter_content():
            f.write(line)
    
    

    五、高级用法

    '''
    requests高级: (了解)
    '''
    
    # 1、SSL (了解)
    # 证书验证(大部分网站都是https)
    # import requests
    # response = requests.get('https://www.gaokao.com/gkpic/') #如果是ssl请求,首先检查证书是否合法,不合法则报错,程序终端
    # #改进1:去掉报错,但是会报警告
    # import requests
    # response = requests.get('https://www.gaokao.com/gkpic/', verify=False) #不验证证书,报警告,返回200
    # print(response.status_code)
    
    # #改进2:去掉报错,并且去掉警报信息
    # import requests
    # import urllib3  # python内置的模块 ---》 requests的前身,urllib ---> urllib2 ---> urllib3
    # urllib3.disable_warnings()  # 关闭警告
    # response = requests.get('https://www.gaokao.com/gkpic/', verify=False)
    # print(response.status_code)
    
    # #改进3:加上证书
    # #很多网站都是https,但是不用证书也可以访问,大多数情况都是可以携带也可以不携带证书
    # #知乎百度等都是可带可不带
    # #有硬性要求的,则必须带,比如对于定向的用户,拿到证书后才有权限访问某个特定网站
    # import requests
    # response=requests.get('https://www.12306.cn',
    #                      # cert=(证书的文件路径),证书是必须真实存在的;
    #                      cert=('/path/server.crt',
    #                            '/path/key'))
    # print(response.status_code)
    
    
    # 2、使用代理
    # 官网链接: http://docs.python-requests.org/en/master/user/advanced/#proxies
    # 代理设置:先发送请求给代理,然后由代理帮忙发送(封ip是常见的事情)
    # import requests
    #
    # proxies = {
    #     # 'http': '192.168.11.11:9743',  # 带用户名密码的代理,@符号前是用户名与密码
    #     # 'http': 'http://localhost:9743',
    #     'https': '163.204.242.181:9999',
    # }
    #
    # response = requests.get('https://www.baidu.com/',
    #                         # proxies: = 代理字典
    #                         proxies=proxies)
    #
    # print(response.status_code)
    
    
    # #支持socks代理,安装:pip install requests[socks]
    # import requests
    # proxies = {
    #     'http': 'socks5://user:pass@host:port',
    #     'https': 'socks5://user:pass@host:port'
    # }
    # respone=requests.get('https://www.12306.cn',
    #                      proxies=proxies)
    #
    # print(respone.status_code)
    
    
    # 3超时设置
    #两种超时:float or tuple
    #timeout=0.1 #代表接收数据的超时时间
    #timeout=(0.1,0.2)#0.1代表链接超时  0.2代表接收数据的超时时间
    
    # import requests
    # try:
    #     response = requests.get('https://www.baidu.com', timeout=0.0001)
    #
    # except Exception as e:
    #     print(e)
    
    # 6、上传文件
    import requests
    response = requests.post(
        'http://httpbin.org/post',
        files={
            'file': open(r'F:程序day100靓仔.jpg', 'rb')
        }
    )
    
    print(response.status_code)
    
  • 相关阅读:
    git 常用命令
    svn常用命令
    mysql的bin或者sbin目录可执行文件
    SQL 函数
    SQL 通配符
    从一个Activity打开另外一个Activity
    断点下载数据
    多线程下载文件
    向服务器发送post请求
    android 查看网络图片
  • 原文地址:https://www.cnblogs.com/guapitomjoy/p/12126491.html
Copyright © 2011-2022 走看看