requests库的使用

requests库的使用

Get 请求

http中最常见的请求之一就是GET请求,尝试用requests构建GET请求

普通示例

import requests
r = requests.get("http://httpbin.org/get")
print(r.text)
print(type(r.text)) 
print(r.json())      
print(type(r.json()))

因为网页返回类型是str,但这个示例中又是特殊的,是json格式
可以直接调用json()方法,返回结果是json格式的字符串转化为字典,但需要注意的是,如果返回结果不是json格式,便会抛出json.decoder.JSONDecodeError异常

抓取网页

上面的请求链接返回的是JsON形式的字符串,那么如果请求普通的网页,则肯定能获得相应的内容了。

import requests
import re

headers = {
    'User-Agent': "Mozilla/5.0(X11; U; Linux 1686)Gecko/20071127 Firefox/2.0.0.11"
}
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)

抓取二进制数据

图片、音频、视频这些文件本质上都是由二进制码组成的,由于有特定的保存格式和对应的解析方式,我们才可以看到这些形形色色的多媒体。所以,想要抓取它们,就要拿到它们的二进制码。

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

POST 请求

简单示例

import requests

headers = {
    'Accept':"application/json, text/javascript, */*; q=0.01",
    'Accept-Encoding': "gzip, deflate",
    'Accept-Language': "zh-CN,zh;q=0.9",
    'Content-Length': "41",
    'Content-Type':"application/x-www-form-urlencoded; charset=UTF-8",
    'Cookie': "JSESSIONID=200F4AF33A50A4218E7A127DAA8D7AA9; browserID=4230492218",
    'Host': "210.38.250.43",
    'Origin': "http://210.38.250.43",
    'Proxy-Connection': "keep-alive",
    'Referer': "http://210.38.250.43/",
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
    'X-Requested-With': "XMLHttpRequest"
}
data = {
    'account': "123",
    'pwd': "456"
}

path_str = "/login!doLogin.action"

r = requests.post("http://210.38.250.43" + path_str,headers = headers,data=data)
print(r.text)
reponse_dict = r.json()
path_str = reponse_dict["msg"]

r = requests.get("http://210.38.250.43" + path_str)
print(r.text)

文件上传

假如有的网站要求需要上传文件,我们也可以用它来实现,这也非常简单

import requests

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

Cookies

调用 cookies属性即可成功得到 Cookies,可以发现它是 RequestCookie]ar类型。然后用 items(方法将其转化为元组组成的列表,遍历输出每一个 Cookie的名称和值,实现 Cookie的遍历解析。

import requests

r = requests.get("https://baidu.com")
print(r.cookies)
for key,value in r.cookies.items():
    print(key + '=' +value)

也可以直接使用cookie来维持登录状态

import requests

headers = {
    'Cookies': '_zap=115f81e8-5f7e-4637-9dca-a3c10b02ea4c; d_c0="AHDkuPpl9Q2PTquzGeA_1ZKzgHIPWwpcgpI=|1532586704"; q_c1=7746b2dbb0e0477385ff08f746e241cb|1532586704000|1523623429000; tgw_l7_route=4860b599c6644634a0abcd4d10d37251; _xsrf=iVT9wOylEpcF1KeC6GBkuHGBAc7K7W5v; capsion_ticket="2|1:0|10:1549859105|14:capsion_ticket|44:Mzk4NDI1N2IwZjQ3NDQ0MDkzNTVhMDVjYzg3NWY3ZDA=|841aabf9e34f95e7c284055277a41ca72c34f258eb467d6ce868e1d74cc93ed7"; z_c0="2|1:0|10:1549859129|4:z_c0|92:Mi4xVVRiZEJBQUFBQUFBY09TNC1tWDFEU1lBQUFCZ0FsVk5PVWRPWFFENk5rbzZFU0UxTWVRZmpialhnd3M2eFZtRVhn|6282e80a2eadab844332de00b3c01e1de1d6e0f06bc608d1ec03dbb8d244bc6c"; tst=r',
    'Host': "www.zhihu.com",
    'User-Agent':"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36"
}
r = requests.get('http://www.zhihu.com',headers= headers)
print(r.text)

会话维持

在 requests中,如果直接利用get()或post()等方法的确可以做到模拟网页的请求,但是这实际上是相当于不同的会话,也就是说相当于你用了两个浏览器打开了不同的页面。设想这样一个场景,第一个请求利用post()方法登录了某个网站,第二次想获取成功登录后的自己的个人信息,你又用了一次get()方法去请求个人信息页面。实际上,这相当于打开了两个浏览器,是两个完全不相关的会话,能成功获取个人信息吗?那当然不能其实解决这个问题的主要方法就是维持同一个会话,也就是相当于打开一个新的浏览器选项卡而不是新开一个浏览器。但是我又不想每次设置 cookies,那该怎么办呢?这时候就有了新的利器— Session对象

import requests

s = requests.Session()
s.get("http://httpbin.org/cookies/set/number/123")
r = s.get("http://httpbin.org/cookies")
print(r.text)

这里我们请求了一个测试网址htp://httpbin.org/cookies/set/number/123。请求这个网址时,可以设置一个 cookie,名称叫作 number,内容是123,随后又请求了htt:/ nttpbin. org/cookies此网址可以获取当前的 Cookies

SSL证书验证

此外,requests还提供了证书验证的功能。当发送HTTP请求的时候,它会检查SSL证书,我们可以使用 verify参数控制是否检查此证书。其实如果不加 verify参数的话,默认是True,会自动验证
如果只设置verify参数为false,我们还是会发现报一个警告,它建议我们给它指定证书。我们可以通过设置忽略警告的方式来屏蔽这个警告;或者通过捕获警告到日志的方式忽略警告

import requests
from requests.packages import urllib3
import logging

urllib3.disable_warnings() #设置忽略警告
logging.captureWarnings(True) #捕获警告到日志
response = requests.get('https://www.12306.cn',verify = False)
print(response.status_code)

当然,我们也可以指定一个本地证书用作客户端证书,这可以是单个文件(包含密钥和证书)或一个包含两个文件路径的元组:

import requests

response = requests.get('https://www.12306.cn',cert=('/path/server.crt','/path/key'))
print(response.status_code)

当然,上面的代码是演示实例,我们需要有crt和key文件,并且指定它们的路径。注意,本地私有证书的key必须是解密状态,加密状态的key是不支持的。

代理设置

对于某些网站,在测试的时候请求几次,能正常获取内容。但是一旦开始大规模爬取,对于大规模且频繁的请求,网站可能会弹出验证码,或者跳转到登录认证页面,更甚者可能会直接封禁客户端的IP,导致一定时间段内无法访问。那么,为了防止这种情况发生,我们需要设置代理来解决这个问题,这就需要用到 proxies参数。可以用这样的方式设置:

import requests

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

requests.get("https://www.taobao.com",proxies = proxies)

Prepared Request

在本机网络状况不好或者服务器网络响应太慢甚至无响应时,我们可能会等待特别久的时间才可能收到响应,甚至到最后收不到响应而报错。为了防止服务器不能及时响应,应该设置一个超时时间,即超过了这个时间还没有得到响应,那就报错。这需要用到 timeout参数。这个时间的计算是发出请求到服务器返回响应的时间。实际上,请求分为两个阶段,即连接( connect)和读取(read)上面设置的 timeout将用作连接和读取这二者的 timeout总和。如果要分别指定,就可以传入一个元组:

import requests 
r = requests.get("http://www.taobao.com",timeout = (5,10))
print(r.status_code)

如果想永久等待,可以直接将 timeout设置为№one,或者不设置直接留空,因为默认是None。这样的话,如果服务器还在运行,但是响应特别慢,那就慢慢等吧,它永远不会返回超时错误的

Prepared Request

可以将请求表示为数据结构,其中各个参数都可以通过一个Request对象来表示。这个数据结构就叫Prepared Request。

from requests import Request,Session

url = 'http://httpbin.org/post'
data = {
    'username': "Lina"
}
headers = {
    'User-Agent':"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36"
}
s = Session()
req = Request('POST',url,data=data,headers=headers)
prepped = s.prepare_request(req)
r = s.send(prepped)
print(r.text)

你可能感兴趣的:(python)