requests
-
requests
Request:浏览器发送信息给该网址所在的服务器,这个过程就叫做HTTP Request。
request中包含
请求方式:请求方式的主要类型是GET,POST两种,另外还有HEAD、PUT、DELETE等。GET 请求的请求参数会显示在URL链接的后面,比如我们打开百度,搜索“图片”,我们会看到请求的URL链接为https://www.baidu.com/s?wd=图片
。而 POST 请求的请求参数会存放在Request内,并不会出现在 URL 链接的后面,比如我们登录知乎,输入用户名和密码,我们会看到浏览器开发者工具的Network页,Request请求有Form Data的键值对信息,那里就存放了我们的登录信息,有利于保护我们的账户信息安全;
- GET
response = requests.get(url,params,kwargs)
带参数 params 的get请求
data = {
'name' : 'jack',
'age' : 20
}
resp = requests.get('http://httpbin.org/get', params=data)
将参数直接写在url中
url=www.xxx.com/?name=yy&age=13
request.get(url)
2. POST
response = requests.post(url,data)
import requests
data = {
'name' : 'jack',
'age' : 20
}
resp = requests.post('http://httpbin.org/post', data=data)
print(resp.text)
一个POST必然是要有一个Form Data的表单提交的,我们只要把信息组成一个字典传给data参数就可以了
文件上传:
# file_content = {'file': (filename, open('{}{}'.format(reports_path, filename), 'rb'), 'application/vnd.ms-excel',{'Expires': '0'})}
files = {'file' : open('logo.gif','rb')}
data={'s':'a','a':{'23':'asd'}}
resp = requests.post('http://httpbin.org/post', files=files,data=data)
files传输的是一个文件的读取二进制流,同时也可以传输data数据,但是跟以往的data不同,以往的data是要json序列化的,这里的data由于有了文件的二进制数据,
请求的载荷改变了,虽然还是字典形式,但是如果字典里的键对应的还是字典就传输不了data数据,需要把字典里的键对应的字典进行json序列化转为字符串,到了解析的接口再转回来。才能使用字典数据
一些参数:
headers
携带请求头发送请求
import requests
url = 'https://www.baidu.com'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
# 在请求头中带上User-Agent,模拟浏览器发送请求
response = requests.get(url, headers=headers)
print(response.content)
# 打印请求头信息
print(response.request.headers)
headers = {
# 从浏览器中复制过来的User-Agent
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',
# 从浏览器中复制过来的Cookie
'Cookie': 'xxx这里是复制过来的cookie字符串'
}
SSL/CA证书验证 verify
requests.get('https://kennethreitz.com', verify=True) # verify参数默认值为True
requests.exceptions.SSLError: hostname 'kennethreitz.com' doesn't match either of '*.herokuapp.com', 'herokuapp.com'
import requests
from requests.packages import urllib3
urllib3.disable_warnings()
requests.get('https://kennethreitz.com', verify=False)
代理使用 proxies
resp = requests.get('http://www.baidu.com', proxies=proxies)
proxies = {
"http": "http://user:pass@10.10.1.10:3128/",
}
proxies = {
"http": 'socks5://user:pass@host:port',
"https": 'socks5://user:pass@host:port'
}
超时设置 timeout
认证设置 auth
from requests.auth import HTTPBasicAuth
resp = requests.get(url, auth=HTTPBasicAuth('username','password'))
假如提示SSL错误的话,就忽略ssl验证 添加verify=False参数
异常处理
import requests
from requests.exceptions import ReadTimeout, ConnectionError, RequestException
try:
resp = requests.get('http://httpbin.org/get', timeout=0.5)
print(resp.status_code)
except ReadTimeout: # 访问超时的错误
print('Timeout')
except ConnectionError: # 网络中断连接错误
print('Connect error')
except RequestException: # 父类错误
print('Error')
cookies
Session 状态保持
对于ajax:
对于ajax发起的请求,通过抓包获取请求的路径,查看要发送的form表单字段。拼接数据,往url发送请求,同时抓包分析该请求的response,看一下 返回的数据格式。
import requests
import json
classKing(object):
def __init__(self, word):
self.url = "http://fy.iciba.com/ajax.php?a=fy"
self.word = word
self.headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
}
self.post_data = {
"f": "auto",
"t": "auto",
"w": self.word
}
def get_data(self):
response = requests.post(self.url, headers=self.headers, data=self.post_data)
# 默认返回bytes类型,除非确定外部调用使用str才进行解码操作
return response.content
def parse_data(self, data):
# 将json数据转换成python字典
dict_data = json.loads(data)
# 从字典中抽取翻译结果
try:
print(dict_data['content']['out'])
except:
print(dict_data['content']['word_mean'][0])
def run(self):
# url
# headers
# post——data
# 发送请求
data = self.get_data()
# 解析
self.parse_data(data)
if __name__ == '__main__':
# king = King("人生苦短,及时行乐")
king = King("China")
king.run()
对于抓包资源的获取,有时正面参数多,难度大,而且有的拼接数据字段在源码中都没有出现,是用js算出来的。
换个方向, 或许参数就少的多,例如换成手机模式,查看抓包信息
处理js
有时候数据并不是直接呈现的,经过了js的转换,这时候就需要顺着js反推数据,才能拼凑好post需要的数据
1 分析页面
解决页面重定向时,前一个页面的资源包不显示的问题
2 定位js文件。
3 分析js文件中生成数据的函数,
4 模拟js运算过程,对数据进行运算。
python中有不少解析js的模块,可以直接使用
5 拼接数据,发送post请求
例子:有道词典
有道中data数据是经过处理的,经过了加密
- 响应对象
response响应对象
exit() if not resp.status_code ==200 else print('Sucessful')
三元判断状态码。 成功打印successful 失败退出
>>>r.request.headers
{'Accept-Encoding': 'identity, deflate, compress, gzip',
'Accept': '*/*', 'User-Agent': 'python-requests/1.2.0'}
>>> r.headers
{
'content-encoding': 'gzip',
'transfer-encoding': 'chunked',
'connection': 'close',
'server': 'nginx/1.0.4',
'x-runtime': '148ms',
'etag': '"e1ca502697e5c9317743dc078f67693f"',
'content-type': 'application/json'
}
>>>resp = requests.get('http://www.baidu.com')
>>>print(resp.cookies)
<RequestsCookieJar[]>
>>>for key, value in resp.cookies.items():
...print(key +'='+ value)
BDORZ=27315
>>> requests.utils.dict_from_cookiejar(r.cookies)
{'BAIDUID': '84722199DF8EDC372D549EC56CA1A0E2:FG=1', 'BD_HOME': '0', 'BDSVRTM': '0'}
requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True)
>>> url ='http://httpbin.org/cookies'
>>> cookies =dict(cookies_are='working')
>>> r =requests.get(url, cookies=cookies)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'
其他