爬虫request库的使用——学习笔记

使用requests

一、基本用法

1、准备工作

安装request库。

pip install request

2、实例引入

request库中以GET方式请求网页的方法就是get()方法

import requests

r = requests.get('https://www.baidu.com/')
print(type(r))
print(r.status_code)
print(type(r.text))
print(r.text)
print(r.cookies)


'''
运行结果:


200




 ç™¾åº¦ä¸€ä¸‹ï¼Œä½ å°±çŸ¥é“  
]> '''

​ 这里调用的get()方法和urllib的urlopen()方法操作相同。得到了一个Response对象,然后分别输出Response的类型、状态码、响应体类型、内容、cookies。

​ 通过运行结果发现,它返回类型是:requests.models.Response

响应体的类型是字符串str,cookies的类型是:RequestsCookieJar。

​ 其他类型的请求依然可以用一句话来完成。

r = requests.post('http://httpbin.org/post')
r = requests.put('http://httpbin.org/post')
r = requests.delete('http://httpbin.org/post')
r = requests.head('http://httpbin.org/post')
r = requests.options('http://httpbin.org/post')

3、GET请求

  • 基本实例

    ​ 首先构造一个最简单的GET请求,请求的连接为http://httpbin.org/get 该网站会判断如果客户端发起的是GET请求的话,它返回相应的请求信息。

    import requests
    
    r = requests.get('http://httpbin.org/get')
    print(r.text)
    
    '''
    运行结果:
    {
      "args": {}, 
      "headers": {
        "Accept": "*/*", 
        "Accept-Encoding": "gzip, deflate", 
        "Host": "httpbin.org", 
        "User-Agent": "python-requests/2.22.0", 
        "X-Amzn-Trace-Id": "Root=1-601a6499-085939cc227cef8e10512ec9"
      }, 
      "origin": "101.27.236.254", 
      "url": "http://httpbin.org/get"
    }
    '''
    

    ​ 返回结果中包含请求头、URL、IP等信息。

    ​ 那么,对于GET请求,如果要附加额外的信息。一般怎么添加呢?

    可以直接写成:

    requests.get('http://httpbin.org/get?name=germey&age=22')
    

    还可以这么写:

    import requests
    
    data = {
        'name': 'germey',
        'age': 22
    }
    r = requests.get('http://httpbin.org/get', params=data)
    print(r.text)
    
    '''
    运行结果:
    {
      "args": {
        "age": "22", 
        "name": "germey"
      }, 
      "headers": {
        "Accept": "*/*", 
        "Accept-Encoding": "gzip, deflate", 
        "Host": "httpbin.org", 
        "User-Agent": "python-requests/2.22.0", 
        "X-Amzn-Trace-Id": "Root=1-601a660f-267a57e67038f33a6a9f8471"
      }, 
      "origin": "101.27.236.254", 
      "url": "http://httpbin.org/get?name=germey&age=22"
    }
    '''
    

    ​ 通过运行结果可以判断,请求链接自动被构造成了:http://httpbin.org/get?name=germey&age=22

    ​ 另外网页返回的数据实际上是个str类型的数据,但是格式是JSON格式的。如果想直接解析返回结果,需要得到一个字典格式的话,可以使用json()方法:

    import requests
    
    r = requests.get('http://httpbin.org/get')
    print(type(r.text))
    print(r.json())
    print(type(r.json()))
    
    '''
    运行结果:
    
    {'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-601a6708-6670d3d14537c91e05517042'}, 'origin': '101.27.236.254', 'url': 'http://httpbin.org/get'}
    
    '''
    

    ​ 调用json方法,就可以将返回的结果是JSON格式的字符串转换为字典。

    ​ 如果返回的结果不是JSON格式的,使用json()方法将会解析错误。抛出json.decoder.JSONDecodeError异常。

  • 抓取网页

    import requests
    import re
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
    }
    
    r = requests.get('https://www.zhihu.com/explore', headers=headers)
    
    pattern = re.compile('explore-feed.*?question_link.*?>(.*?)', re.S)
    titles = re.findall(pattern, r.text)
    print(titles)
    

    ​ 这里加入了headers,其中包含了User-Agent。也就是浏览器标识信息。如果没有知乎进制爬取。

    ​ 使用了正则表达式来匹配了所有问题内容。

  • 抓取二进制数据

    ​ 如果想要抓取图片、音频、视频等文件,应该怎么办?它们这些文件本质上都是由二进制组成的,想要抓取它们,就要拿到他们的二进制码。

    ​ 以爬取GitHub的站点图标为例:

    import requests
    
    r = requests.get('https://github.com/favicon.ico')
    print(r.text)
    print(r.content)
    
    '''
    r.content 返回的是response的二进制形式
    '''
    

    ​ 将刚提取的照片,保存下来:

    import requests
    
    r = requests.get('https://github.com/favicon.ico')
    with open('favicon.ico', 'wb') as f:
        f.write(r.content)
    

    ​ 这里利用了open()方法,它的第一个参数是文件名称,第二个参数代表以二进制形式打开,可以想文件写入二进制数据。

    ​ 运行结果,可以发现在文件夹中出现了名为favicon.icn的图标。

    ​ 同样,音频和视频也可以用同样的方式获取。

  • 添加headers

    ​ 我们可以通过添加headers参数来传递请求头信息。

    ​ 比如,上面的知乎例子中,如果不传递请求头,就不能正常请求:

    import requests
    
    r = requests.get('https://www.zhihu.com/explore')
    print(r.status_code)
    
    # 结果:403
    

    如果添加了请求头:

    import requests
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
    }
    
    r = requests.get('https://www.zhihu.com/explore', headers=headers)
    print(r.status_code)
    
    # 结果:200
    

4、POST请求

​ 使用requests发送POST请求,同样非常简单:

import requests

data = {
    'name': 'gremey',
    'age': 22
}
r = requests.post('http://httpbin.org/post', data=data)
print(r.text)

​ 这里请求的是http://httpbin.org/post,该网站可以判断如果请求是POST方式,就把相关信息返回。

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "age": "22", 
    "name": "gremey"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "18", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.22.0", 
    "X-Amzn-Trace-Id": "Root=1-601aa10d-42d913880494d70138da87b0"
  }, 
  "json": null, 
  "origin": "101.**.***.***", 
  "url": "http://httpbin.org/post"
}

5、响应

​ text:响应的内容 ,

​ content:响应的内容(二进制格式),

​ status_code:状态码,

​ headers:响应头,

​ cookies:Cookies,

​ url:得到URL,

​ history:请求历史,

requests还提供了一个内置的状态码查询对象 requests.codes:

import requests

r = requests.get('http://www.jianshu.com')
if r.status_code == requests.codes.ok:
    print(r.status_code)
else:
    print(r.status_code)

二、高级用法

1、文件上传

import requests

files = {'file': open('favicon.ico', 'rb')}
r = requests.post('http://httpbin.org/post', files=files)
print(r.text)

'''
{
  "args": {}, 
  "data": "", 
  "files": {
    "file": "data:application/octet-stream;base64,AAA......AA="
  }, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "6666", 
    "Content-Type": "multipart/form-data; boundary=a31bbf46d658d1fc60329fbddb902743", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.22.0", 
    "X-Amzn-Trace-Id": "Root=1-601b9a26-56bdf162129937eb1bfbb260"
  }, 
  "json": null, 
  "origin": "101.27.236.254", 
  "url": "http://httpbin.org/post"
}
'''

​ 先创建一个字典,字典里的值就是文件。然后在使用POST请求的时候,给参数复制于刚刚建立的文件字典。

​ 通过结果观察可知道,上传文件会单独创建一个files字段。该字段内容就是文件字典内的内容。而form字段为空,这证明文件上传部分会单独有一个files字段来标识。

2、Cookies

import requests

r = requests.get('https://www.baidu.com')
print(r.cookies)
for key,value in r.cookies.items():
    print(key, '=', value)
    
'''
]>
BDORZ = 27315
'''

​ 首先调用cookies属性即可获得Cookies,可以发现它是RequestsCookieJar类型的。然后调用items()方法将其转换为元组组成的列表,遍历每一个Cookie的名称和值,实现Cookie的遍历和解析。

​ 当然,也可以用cookies来维持登录状态,以知乎为例:

import requests

headers = {
    'User-Agent': 'Mozi......',
    'Cookie':'_zap=3f......'
}

r = requests.get('https://www.zhihu.com', headers=headers)
print(r.text)

​ 也可以通过cookies参数来设置,这样就需要先构建一个RequestsCookieJar对象。

import requests

cookies = '_zap=3f00e0......'

jar = requests.cookies.RequestsCookieJar()

headers = {
    'Host': 'www.zhihu.com',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.1'
                  '46 Safari/537.36'
}

for cookie in cookies.split(';'):	# 使用分号进行分割
    key, value = cookie.split('=', 1)	# 使用等号进行分割,分割1次
    jar.set(key, value)

r = requests.get('http://www.zhihu.com', cookies=jar, headers=headers)
print(r.text)

​ 设置一个cookies变量,保存一个cookie。

​ 设置一个headers,保存User-Agent,Host等一些请求头。

​ 实例化一个RequestsCookieJar对象。

​ 使用for循环将cookies变量里的cookie使用split()方法按照分号(;)进行切割。然后在对切割后的cookie使用split()方法用等号切割,第二个参数1,表示切割一次。等号前的内容保存到key中,等好后的内容保存到value中。然后在使用set()方法,将key和value添加到实例化的RequestsCookieJar对象中。

3、会话维持

​ 在requests中,如果直接使用get()或post()请求虽然可以做到模拟网页请求,但是实际上相当于不同的会话,也就是说相当于打开了两个浏览器打开了不同的页面。

​ 假设:第一个请求利用post()方法登陆了某个网站,第二次想获取网站成功登陆后的自己的个人信息,你又用get()方法去请求个人信息页面。实际上,这相当于打来了两个浏览器。是两个完全不相关的会话,不能获取到个人信息。

​ 解决办法:维持同一个会话,也就是相当于打开一个新浏览器选项卡而不是在新开一个浏览器。但是又不想重复设置cookies,就需要利用Session对象了。

import requests

requests.get('http://httpbin.org/cookies/set/number/123456789')
r = requests.get('http://httpbin.org/cookies')
print(r.text)

'''
requests.get('http://httpbin.org/cookies/set/number/123456789')
上面请求的网址可以设置一个cookie,名为number,内容是123456789

结果:
{
  "cookies": {}
}
'''

​ 通过结果看到,cookies字段为空,并没有刚刚设置的cookie。

​ 下面使用Session对象试试:

import requests

s = requests.session()
s.get('http://httpbin.org/cookies/set/number/123456789')
r = s.get('http://httpbin.org/cookies')
print(r.text)

'''
结果:
{
  "cookies": {
    "number": "123456789"
  }
}
'''

​ 通过上面的结果,发现cookies字段有内容了,键是number,值是123456789。

​ 实现步骤:

​ 先使用requests.session()生成一个Session对象。

​ 然后使用Session对象请求http://httpbin.org/cookies/set/number/123456789,生成一个cookie。

​ 再使用Session对象调用get()方法去访问http://httpbin.org/cookies。

4、SSL证书验证

​ get()方法或者post()方法中,设置verify参数,True:自动验证,False:不验证

5、代理设置

​ 需要用到:proxies参数:

import requests

proxies = {
    'http': 'http://10.10.1.10:3128',
    'https': 'https://10.10.1.10:1080'
}

requests.get('https://www.toabo.com', proxies=proxies)

​ 若需要使用HTTP Basic Auth代理,可以使用类似http://ueser:password@host:port这样的语法来设置

import requests

proxies = {
    'http': 'http://user:[email protected]:3128'
}
requests.get('https://www.toabo.com', proxies=proxies)

​ 除了基本代理,还可以使用SOCKS协议代理

​ 首先需要安装socks这个库

pip install requests[socks]

​ 然后就可以使用SOCKS协议代理了

import requests

proxies = {
    'http': 'socks5://user:password@host:port',
    'https': 'socks5://user:password@host:port'
}

requests.get('https://www.toabo.com', proxies=proxies)

6、超时设置

​ 需要用到timeout参数

import requests

requests.get('http://www.taobao.com', timeout=1)

提示timeout分为两个阶段,连接和读取

上面设置的timeout是用作连接和读取这二者的timeout的总和。

如果要分别制定,就可以传入一个元组:

import requests

requests.get('http://www.taobao.com', timeout=(5, 11))

还可以那个timeout设置为None,或者不设置直接留空,因为默认是None。这样就是不设置超时:

import requests

requests.get('http://www.taobao.com', timeout=None)

7、身份认证

可以用rquests.auth里面的HTTPBasicAuth

import requests
from requests.auth import HTTPBasicAuth

r = requests.get('htpps://......', auth=HTTPBasicAuth('username', 'password'))
print(r.status_code)


# 简写
import requests
from requests.auth import HTTPBasicAuth

r = requests.get('htpps://......', auth=('username', 'password'))
print(r.status_code)

还提供了其他认证,比如OAuth认证。

pip install requests_oauthlib
import requests
from requests_oauthlib import OAuth1
url = 'https://api.twiter.com/1.1/account/verify_credertials.json'
auth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET', 'USER_OAUTH_TOKEN', 'USER_OAUTH_TOKEN_SECRET')
requests.get(url, auth=auth)

8、Prepared Request

​ 将请求表示为数据结构。

from requests import Request, Session

url = 'http://httpbin.org/post'
data = {
    'name': 'dong'
}
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.14'
                  '6 Safari/537.36'
}

s = Session()
req = Request(method='post', url=url, data=data, headers=headers)
prepped = s.prepare_request(req)
r = s.send(prepped)
print(r.text)


'''
结果:
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "name": "dong"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "9", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36", 
    "X-Amzn-Trace-Id": "Root=1-601e8c1b-6b0b817b39c1cf05141f0c75"
  }, 
  "json": null, 
  "origin": "101.27.236.254", 
  "url": "http://httpbin.org/post"
}	`
'''

你可能感兴趣的:(爬虫,爬虫,学习,python)