一, Ruquest 模块基础
requests 模块可以模拟浏览器发送多种请求方式
- import requests
- r = requests.get('https://api.github.com/events')
- r = requests.post('http://httpbin.org/post', data = {
- 'key':'value'
- })
- r = requests.put('http://httpbin.org/put', data = {
- 'key':'value'
- })
- r = requests.delete('http://httpbin.org/delete')
- r = requests.head('http://httpbin.org/get')
- r = requests.options('http://httpbin.org/get')
二, 基于 GET 请求
1. 基本请求
- import requests
- response=requests.get('http://dig.chouti.com/')
- print(response.text)
2. 带参数的 GET 请求(params,headers)
- import requests
- # 请求方式
- kwords = input('请输入关键字:>>>').strip()
- # 使用 urlencode 可以解析中文
- url = "https://www.baidu.com/s?"
- params = {'wd': kwords}
- # 请求头
- baidu_headers = {
- "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) ApplewebKit/537.36 (Khtml, like Gecko) Chrome/77.0.3865.120 Safari/537.36 chrome-extension",
- 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
- }
- # 发送请求
- response = requests.get(url,
- params=params,
- headers=baidu_headers,
- )
- print(response.status_code) # 响应状态码
- # print(response.text) # 返回的 HTML
- # 保存数据
- with open('search1.html', 'w', encoding='utf-8') as f:
- f.write(response.text)
- print('保存成功')
3. 带参数的 GET 请求(cookies)
- # 基于 get 请求携带参数 cookies, 以访问 GitHub 邮箱示范
- import requests
- url = 'https://github.com/settings/emails'
- cookies = {
- 'user_session':"Osrktx19GnRnCYy0eVgixmEc637QGQDaZ7Upi30RI6uG-WWk"
- }
- response = requests.get(url,cookies=cookies) #GitHub 对请求头没有什么限制, 我们无需定制 user-agent, 对于其他网站可能还需要定制
- print("928990486@qq.com" in response.text) # True
三, 基于 POST 请求
1.get 请求与 post 请求的区别
#GET 请求
HTTP 默认的请求方法就是 GET
* 没有请求体
* 数据必须在 1K 之内!
* GET 请求数据会暴露在浏览器的地址栏中
GET 请求常用的操作:
1. 在浏览器的地址栏中直接给出 URL, 那么就一定是 GET 请求
2. 点击页面上的超链接也一定是 GET 请求
3. 提交表单时, 表单默认使用 GET 请求, 但可以设置为 POST
#POST 请求
(1). 数据不会出现在地址栏中
(2). 数据的大小没有上限
(3). 有请求体
(4). 请求体中如果存在中文, 会使用 URL 编码!
#!!!requests.post()用法与 requests.get()完全一致, 特殊的是 requests.post()有一个 data 参数, 用来存放请求体数据
2, 发送 post 请求, 模拟浏览器的登录行为
注意:
1, 对于登录来说, 应该输错用户名或密码然后分析抓包流程, 如果输对了浏览器就跳转了, 就没法分析了, 抓不到包了,
2, 要做登录的时候一定记得要把 cookie 先清除;
3,requests.session(): 中间的 cookie 都不用自己分析了, 有用的没用的都给放进来了,
- 4,response.cookie.get_dict() #获取 cookie
- '''
- 一 目标站点分析
- 浏览器输入 https://github.com/login
- 然后输入错误的账号密码, 抓包
- 发现登录行为是 post 提交到: https://github.com/session
- 而且请求头包含 cookie
- 而且请求体 (form data) 包含:
- commit: Sign in
- utf8:
- authenticity_token: NG74Lb4wcJn/emTlJS/A71Wk2WJioAwqgelWqBvPoqe0aD8tWsn8r+088bFUCOv7FY+MI9JmOy+ojP3pisz35w==ga_id: 804200945.1577712060
- login: 928990486@qq.com
- password: 123456
- webauthn-support: supported
- webauthn-iuvpaa-support: unsupported
- required_field_55c0:
- timestamp: 1577713659056
- timestamp_secret: 65a511d2fd997e58b721ba390196372e6beb012c12a69d57156c9a2b20c267ea
- 二 流程分析
- 先 GET:https://github.com/login 拿到初始 cookie 与 authenticity_token 与 timestamp_secret 随机加密字符串
- 返回 POST:https://github.com/session, 带上初始 cookie, 带上请求体(authenticity_token, 用户名, 密码等)
- 最后拿到登录 cookie
- ps: 如果密码是密文形式, 则可以先输错账号, 输对密码, 然后到浏览器中拿到加密后的密码, github 的密码是明文
- '''
- import requests
- import re
- # 第一次请求
- login_headers = {
- "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36 chrome-extension",
- }
- r1 = requests.get('https://github.com/login',headers=login_headers)
- # 2)先解析获取 authenticity_token 与 timestamp_secret, 通过 re 模块实现
- authenticity_token=re.findall(r'<input type="hidden"name="authenticity_token"value="(.*?)"/>',
- r1.text,
- re.S)[0] # re.S 代表全文检索
- timestamp_secret = re.findall('<input type="hidden"name="timestamp_secret"value="(.*?)"class="form-control"/>',
- r1.text,
- re.S)[0]
- print(authenticity_token)
- # 第二次请求: 带着初始 cookie 和 TOKEN 发送 POST 请求给登录页面, 带上账号密码通过 post 请求访问 https://github.com/session
- form_data = {
- 'commit': 'Sign in',
- 'utf8': '',
- 'authenticity_token':authenticity_token,
- 'login': '928990486@qq.com',
- 'password': 'qq7855993',
- 'webauthn-support': 'supported',
- 'webauthn-iuvpaa-support': 'unsupported',
- 'required_field_55c0':'',
- 'timestamp': 1577717454909,
- 'timestamp_secret': timestamp_secret
- }
- r2 = requests.post('https://github.com/session',
- data=form_data,
- cookies=r1.cookies,
- )
- login_cookie = r2.cookies
- # 第三次请求: 以后的登录, 拿着 login_cookie 就可以, 比如访问一些个人配置
- r4=requests.get('https://github.com/settings/emails',
- cookies=login_cookie
- )
- print('928990486@qq.com' in r4.text) #True
四, Response 属性
- import requests
- headers = {
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
- }
- response = requests.get('https://www.jianshu.com', headers=headers)
- '''
- # response 属性:
- '''
- # 1. 响应状态码(*******)
- print(response.status_code)
- # 2. 响应文本(HTML 文本)(*******)
- # print(response.text)
- # 3. 响应的 cookies(*******) 注意: 有些网站可以直接传入 cookies=cookies 对象, 有些需要先转换成 dict 类型
- print(type(response.cookies))
- # 4. 将 cookies 对象转成 dict 类型
- print(type(response.cookies.get_dict()))
- # 5. 将 cookies 对象转成 list 类型
- print(type(response.cookies.items()))
- response = requests.get('https://www.baidu.com', headers=headers)
- # 有些网站的默认编码不是 utf-8, 会出现中文错乱
- # print(response.text)
- # 5. 响应编码格式(*******)
- print(response.encoding) # ISO-8859-1
- # 解决字符编码不对应导致的数据展示错乱问题
- response.encoding = 'utf-8'
- print(response.encoding) # utf-8
- # print(response.text)
- # 6. 返回的二进制数据(*******)
- # 一般用于爬取图片, 视频, 音频
- print(response.content)
- # 7. 获取当前网站的 url 地址
- print(response.url)
- # 8. 获取网站返回的 JSON 数据
- # print(response.JSON())
- import JSON
- response = requests.get('https://landing.toutiao.com/api/pc/realtime_news/')
- print(response.status_code)
- # print(response.text)
- print(JSON.loads(response.text)) # 解析 JSON 数据的第一种方式
- print(response.JSON()) # 解析 JSON 数据的第二种方式
- # 9. 获取图片二进制流数据, 并且保存到本地
- response = requests.get('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1577801361635&di=d9fb985650a3fbf2702cf1345fd45a3a&imgtype=0&src=http://inews.gtimg.com/newsapp_bt/0/8709968837/640')
- print(response.status_code)
- # 注意: 二进制数据有可能会很大
- print(response.content)
- # 10. iter_content: 将二进制数据装进一个迭代器中
- with open('靓仔. jpg', 'wb') as f:
- # f.write(response.content)
- # iter_content: 将二进制数据装进一个迭代器中
- for line in response.iter_content():
- f.write(line)
五, 高级用法
- '''
- requests 高级: (了解)
- '''
- # 1,SSL (了解)
- # 证书验证(大部分网站都是 https)
- # import requests
- # response = requests.get('https://www.gaokao.com/gkpic/') #如果是 ssl 请求, 首先检查证书是否合法, 不合法则报错, 程序终端
- # #改进 1: 去掉报错, 但是会报警告
- # import requests
- # response = requests.get('https://www.gaokao.com/gkpic/', verify=False) #不验证证书, 报警告, 返回 200
- # print(response.status_code)
- # #改进 2: 去掉报错, 并且去掉警报信息
- # import requests
- # import urllib3 # python 内置的模块 ---》 requests 的前身, urllib ---> urllib2 ---> urllib3
- # urllib3.disable_warnings() # 关闭警告
- # response = requests.get('https://www.gaokao.com/gkpic/', verify=False)
- # print(response.status_code)
- # #改进 3: 加上证书
- # #很多网站都是 https, 但是不用证书也可以访问, 大多数情况都是可以携带也可以不携带证书
- # #知乎 \ 百度等都是可带可不带
- # #有硬性要求的, 则必须带, 比如对于定向的用户, 拿到证书后才有权限访问某个特定网站
- # import requests
- # response=requests.get('https://www.12306.cn',
- # # cert=(证书的文件路径), 证书是必须真实存在的;
- # cert=('/path/server.crt',
- # '/path/key'))
- # print(response.status_code)
- # 2, 使用代理
- # 官网链接: http://docs.python-requests.org/en/master/user/advanced/#proxies
- # 代理设置: 先发送请求给代理, 然后由代理帮忙发送(封 ip 是常见的事情)
- # import requests
- #
- # proxies = {
- # # 'http': '192.168.11.11:9743', # 带用户名密码的代理,@符号前是用户名与密码
- # # 'http': 'http://localhost:9743',
- # 'https': '163.204.242.181:9999',
- # }
- #
- # response = requests.get('https://www.baidu.com/',
- # # proxies: = 代理字典
- # proxies=proxies)
- #
- # print(response.status_code)
- # #支持 socks 代理, 安装: pip install requests[socks]
- # import requests
- # proxies = {
- # 'http': 'socks5://user:pass@host:port',
- # 'https': 'socks5://user:pass@host:port'
- # }
- # respone=requests.get('https://www.12306.cn',
- # proxies=proxies)
- #
- # print(respone.status_code)
- # 3 超时设置
- # 两种超时: float or tuple
- #timeout=0.1 #代表接收数据的超时时间
- #timeout=(0.1,0.2)#0.1 代表链接超时 0.2 代表接收数据的超时时间
- # import requests
- # try:
- # response = requests.get('https://www.baidu.com', timeout=0.0001)
- #
- # except Exception as e:
- # print(e)
- # 6, 上传文件
- import requests
- response = requests.post(
- 'http://httpbin.org/post',
- files={
- 'file': open(r'F:\ 程序 \ day100 \ 靓仔. jpg', 'rb')
- }
- )
- print(response.status_code)
来源: https://www.cnblogs.com/guapitomjoy/p/12126491.html