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)

猜你喜欢

转载自www.cnblogs.com/hjnzs/p/12563039.html