zoukankan      html  css  js  c++  java
  • requests模块使用一

    1、安装与简介

    Urllib和requests模块是python中发起http请求最常见的模块,但是requests模块使用更加方便简单。

    pip install requests
    

    2、GET请求

    2.1、格式
    response = requests.get(
    			url=请求url地址,
    			headers = 请求头字典,
    			params=请求参数字典,
    		)
    
    2.2、基本使用
    import requests
    params= {'key1': 'value1', 'key2': 'value2'}
    headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
    }
    r = requests.get("http://httpbin.org/get", params=params,headers=headers)
    print(r.text)
    
    2.3、爬取百度贴吧关键字下的所有页面,保存至文件夹中
    2.3.1获取全部页面url的两个方法
    • 同一个网站下,很大一部分网页,只需要修改get请求参数,就可以达到访问不同页面的效果,我们可以利用这个特性,通过找出url中的特殊参数,构建url列表,达到全部抓取的效果

      • https://tieba.baidu.com/f?kw=%E6%AD%A6%E6%B1%89&ie=utf-8&cid=&tab=corearea&pn=0  (第一页)
        https://tieba.baidu.com/f?kw=%E6%AD%A6%E6%B1%89&ie=utf-8&cid=&tab=corearea&pn=50(第二页)
        例如 百度贴吧页面的url,刚好符合,我们发现修改pn参数的值就可以达到翻页效果。
        
    • 通过对第一个页面的内容进行提取,找出下一个页面的url地址,直接上代码,我这里使用正则去提取下一页url。

      • import os
        import requests
        from urllib.parse import quote
        import re
        
        class Tieba(object):
            def __init__(self, kw, path='.'):
                self.kw = kw
                self.base_url = f"https://tieba.baidu.com/f?kw={quote(self.kw)}&ie=utf-8&cid=&tab=corearea&pn=0"
                self.headers = {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
                }
                self.path = path
                self.page = 1
        
            def get_html(self):
                res = requests.get(url=self.base_url, headers=self.headers)
                return res.content.decode()
        
            def get_next_url(self, content):
                next_url = re.search(r'<a href="(.*?)" class="next pagination-item " >下一页&gt;</a>', content)
                self.base_url = 'https:' + next_url.group(1) if next_url else None
        
            def save_file(self, content):
                sub_path = os.path.join(self.path, self.kw)
                if not os.path.exists(sub_path):
                    os.mkdir(sub_path)
                filename = os.path.join(sub_path, self.kw + str(self.page) + '.html')
                with open(filename, 'w', encoding='utf-8') as file:
                    file.write(content)
        
            def run(self):
                while self.base_url:
                    print(self.base_url)
                    content = self.get_html()
                    self.save_file(content)
                    self.get_next_url(content)
                    self.page += 1
        
        
        if __name__ == '__main__':
            t = Tieba('武汉')
            t.run()
        
        

    3、POST请求

    3.1、格式
    response = requests.get(
    			url=请求url地址,
    			headers = 请求头字典,
    			data=表单数据字典,
    		)
    
    3.2、简单使用
    import requests
    headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
    }
    data={
    'name':'花花',
    'age':18
    }
    r = requests.post('http://httpbin.org/post', data = data,headers=headers)
    print(r.text)
    

    4、数据分类

    1、结构化数据:能用关系型数据库描述的数据。
    特点:数据以行为单位,一行数据表示一个实体的信息,每一行的数据的属性是相同的。
    举例:关系数据库中存储的表
    处理方法:sql---结构化查询语言---语言---可以在关系型数据库中对数据的操作。
    2、半结构化数据:拥有字描述结构数据
    特点:包含相关标记,用来分隔语义元素以及对记录和字段进行分层----也别成为自描述结构
    举例:html,xml,json。
    处理方法:正则,xpath(xml,html)
    3、非结构化数据:
    特点:没有固定结构的数据。
    举例:文档,图片,视频,音频等等,都是通过整体存储二进制格式来保存的,一般为视频,音乐等。
    处理:直接保存,但是需要注意文件名后缀

    5、获取响应

    5.1、response对象的常用方法
    import requests
    res=requests.get('https://www.baidu.com/more/')
    print(res.apparent_encoding)  #页面真实编码
    print(res.encoding)           #页面推测编码
    print(res.url)                #请求url
    print(res.status_code)        #返回状态码
    print(res.headers)			  #响应头
    print(res.request.headers)    #请求头
    print(res.request.url)        #请求url
    
    #结果
    utf-8
    ISO-8859-1
    https://www.baidu.com/more/
    200
    {'Accept-Ranges': 'bytes', 'Cache-Control': 'max-age=86400', 'Content-Encoding': 'gzip', 'Content-Length': '10725', 'Content-Type': 'text/html', 'Date': 'Sun, 22 Mar 2020 14:42:49 GMT', 'Etag': '"aebd-59bafefa98680"', 'Expires': 'Mon, 23 Mar 2020 14:42:49 GMT', 'Last-Modified': 'Thu, 09 Jan 2020 07:27:06 GMT', 'P3p': 'CP=" OTI DSP COR IVA OUR IND COM ", CP=" OTI DSP COR IVA OUR IND COM "', 'Server': 'Apache', 'Set-Cookie': 'BAIDUID=2886A8C54AD6E00BAD273F89AE0B92F5:FG=1; expires=Mon, 22-Mar-21 14:42:49 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1, BAIDUID=2886A8C54AD6E00B93A795B185A4330E:FG=1; expires=Mon, 22-Mar-21 14:42:49 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1', 'Vary': 'Accept-Encoding,User-Agent'}
    {'User-Agent': 'python-requests/2.22.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
    https://www.baidu.com/more/
    
    5.2、返回字符串,使用text方法,上面都是使用此方法,返回字符串格式的网页内容。
    import requests
    res=requests.get('https://www.baidu.com/more/')
    print(res.text)
    

    但是需要考虑返回字符串的编码问题,不然容易导致乱码。我们可以摁 F12查看网页源代码,查看当前网页的编码也可以通过apparent_encoding方法查看。

    我们再用代码获取网页

    import requests
    res=requests.get('https://www.baidu.com/more/')
    print(res.encoding)
    ISO-8859-1
    

    此时发现返回的内容使用的是ISO-8859-1编码,由此可知,打印出来的内容一定会乱码。

    我们有两个方法,来防止乱码

    • 1、自己指定编码

      • import requests
        res=requests.get('https://www.baidu.com/more/')
        res.encoding='utf-8'
        print(res.text)
        
    • 2、先接受bytes内容,然后在解码

      • import requests
        res=requests.get('https://www.baidu.com/more/')
        print(res.content.decode('utf-8'))
        
    5.3、返回bytes类型数据,一般用于视频,音乐等数据,使用content,方法
    import requests
    
    res = requests.get('https://www.baidu.com/img/superlogo_c4d7df0a003d3db9b65e9ef0fe6da1ec.png?where=super')
    
    with open('logo.png', 'wb') as file:
        file.write(res.content)
    
    5.4、返回json数据
    5.4.1、什么是json

    json是一种数据交换的格式,json其实是在js语言中,用'字符串'的形式来表示json中的对象和数组的一种技术,所以json本质上是字符串。

    5.4.2、python中如何进行json与python数据类型转换

    可以使用 json 模块将数据转成python中的数据类型,再进行数据提取。

    json_str:json类型数据
    json.loads(json_str)--->python的list或者字典
    json.dumps(python的list或者字典)--->json_str
    

    我在这里使用了jsonpath模块,进行数据提取。

    具体使用方法可参考如下网址:https://goessner.net/articles/JsonPath/

    例1、百度翻译
    import requests
    from jsonpath import jsonpath
    
    
    def fanyi(kw):
        s = 'https://fanyi.baidu.com/sug'
        data = {
            'kw': kw
        }
        res = requests.post(url=s, data=data)
        jp = jsonpath(res.json(), '$.data.*')  #注意res.json(),数据类型为python内置类型,他不是字符串
        for line in jp:
            print(line.get('k', None), line.get('v', None))
    
    
    if __name__ == '__main__':
        kw = input('请输入需要查询的单词>>>:')
        fanyi(kw)
    
    例2、金山词霸翻译
    import requests
    from jsonpath import jsonpath
    
    
    def fanyi(kw):
        s = 'http://fy.iciba.com/ajax.php?a=fy'
        data = {
            'w': kw
        }
    
        headers = {
            'Referer': 'http://fy.iciba.com/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
        }
    
        res = requests.post(url=s, data=data, headers=headers)
        jp = jsonpath(res.json(), '$..word_mean.*.')
        if not jp:
            jp = jsonpath(res.json(), '$..out')
    
        for line in jp:
            print(line)
    
    
    if __name__ == '__main__':
        kw = input('请输入需要查询的单词>>>:')
        fanyi(kw)
    
    例3、高德地图天气查询
    import requests
    from jsonpath import jsonpath
    
    
    class Weather():
        def __init__(self, city):
            self.code_url = 'https://www.amap.com/service/cityList?'
            self.headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
            }
            self.city = city
            self.weather_url = 'https://www.amap.com/service/weather?adcode={}'
    
        def __get_code(self):
            res = requests.get(self.code_url, headers=self.headers)
            jp = jsonpath(res.json(), '$.data.cityByLetter.*.*')
            jp_dic = {i.get('name'): i.get('adcode') for i in jp}
            return jp_dic.get(self.city)
    
        def __get_weather_json(self, code):
            self.weather_url = self.weather_url.format(code)
            return requests.get(self.weather_url, headers=self.headers).json()
    
        def __parse_content(self, content):
            jp = jsonpath(content, '$.data.data.[0].*')
            info_dic = {
                '查询时间': jp[0],
                '天气情况': jsonpath(jp, '$.*.weather_name')[0],
                '实时温度': jsonpath(jp, '$.*.temperature')[0],
                '最高温度': jsonpath(jp, '$.*.*.max_temp')[0],
                '最低温度': jsonpath(jp, '$.*.*.min_temp')[0],
                '风向': jsonpath(jp, '$.*.*.wind_direction_desc')[0]
    
            }
            return info_dic
    
        def view(self):
            code = self.__get_code()
            if code:
                content = self.__get_weather_json(code)
                res = self.__parse_content(content)
                print('查询城市为:',self.city)
                for i in res:
                    print(i, ':', res[i])
            else:
                print('错误城市...')
    
    
    if __name__ == '__main__':
        t = Weather('衡阳')
        t.view()
    
    
  • 相关阅读:
    【并查集】bzoj1015 [JSOI2008]星球大战starwar
    【二分】bzoj2083 [Poi2010]Intelligence test
    【分块答案】【最小生成树】【kruscal】bzoj1196 [HNOI2006]公路修建问题
    【莫队算法】【权值分块】bzoj3809 Gty的二逼妹子序列
    【莫队算法】【权值分块】bzoj3236 [Ahoi2013]作业
    【分块答案】【最小割】bzoj1532 [POI2005]Kos-Dicing
    【费用流】bzoj3280 小R的烦恼
    【最小路径覆盖】【二分图】【最大流】【Dinic】bzoj2150 部落战争
    【枚举】【二分答案】【分块答案】【BFS】【最大流】【Dinic】bzoj1189 [HNOI2007]紧急疏散evacuate
    【最短路】【spfa】【最小割】【Dinic】bzoj1266 [AHOI2006]上学路线route
  • 原文地址:https://www.cnblogs.com/hjnzs/p/12563039.html
Copyright © 2011-2022 走看看