1.post请求
get请求与post请求的区别
从网上找到很好的解释:
一.在我大万维网世界中,TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象。但是如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车拦堵在路上,整个交通系统一定会瘫痪。为了避免这种情况发生,交通规则HTTP诞生了。HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。如果是POST请求,就要在车上贴上POST的标签,并把货物放在车厢里。当然,你也可以在GET的时候往车厢内偷偷藏点货物,但是这是很不光彩;也可以在POST的时候在车顶上也放一些数据,让人觉得傻乎乎的。HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本。
二.在我大万维网世界中,还有另一个重要的角色:运输公司。不同的浏览器(发起http请求)和服务器(接受http请求)就是不同的运输公司。 虽然理论上,你可以在车顶上无限的堆货物(url中无限加参数)。但是运输公司可不傻,装货和卸货也是有很大成本的,他们会限制单次运输量来控制风险,数据量太大对浏览器和服务器都是很大负担。业界不成文的规定是,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。
GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
三.GET和POST还有一个重大区别,简单的说:
GET产生一个TCP数据包;POST产生两个TCP数据包。
长的说:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。
因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?
1. GET与POST都有自己的语义,不能随便混用。
2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
''''''
'''
post请求登陆github
'''
import requests
import re
# 一 访问login页获取token信息
'''
请求url:
https://github.com/login
请求方式:
GET
响应头:
Set-Cookie
请求头:
Cookie
User-Agent
'''
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
}
response = requests.get(url='https://github.com/login', headers=headers)
# print(response.text)
# 把login页返回的cookies信息转换成字典
login_cookies = response.cookies.get_dict()
authenticity_token = re.findall('<input type="hidden" name="authenticity_token" value="(.*?)" />', response.text, re.S)[0]
print(authenticity_token)
# 二 往sessionurl发送POST请求
'''
请求url:
https://github.com/session
请求方式:
POST
请求头:
# 上一次请求从哪里来
Referer: https://github.com/login
Cookie:...
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36
请求体:
只有POST请求才会有请求体。
commit: Sign in
utf8: ✓
authenticity_token:
VX79esFc0YPdR1UFzUM/6MTRZOlYQ0btF5k2/x7uZea0x2E6W4bmRpwHsaCBN+096PaWNkcQjJOsyUzUqsAhIw==
LLWlTr0qLcYC74hn7OI7IlyeB9rZei9737Lqtzz0sKTgY7Js7pUUhZ6bNC6lCkS+OHfVukkbTejjd0BnjPvGUg==
login: tankjam1
password: *****
webauthn-support: unsupported
'''
# 拼接请求头信息
headers2 = {
'Referer': 'https://github.com/login',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36',
}
# 拼接请求体信息
form_data = {
"commit": "Sign in",
"utf8": "✓",
"authenticity_token": authenticity_token,
"login": "tankjam",
"password": "kermit46709394",
"webauthn-support": "unsupported",
}
# 往session地址发送post请求
# 携带请求头、请求体、login页的cookies信息
response2 = requests.post(url='https://github.com/session', data=form_data, headers=headers2, cookies=login_cookies)
print(response2.status_code)
# print(response2.text)
with open('github.html', 'w', encoding='utf-8') as f:
f.write(response2.text)
2.request的高级用法
import requests
response=requests.get('https://www.baidu.com/')
# reponse响应
# 获取响应状态码
print(response.status_code)
# 获取url地址
print(response.url )
# 获取文本
print(response.text)
# 获取二进制流
print(response.content)
# 获取页面请求头信息
print(response.headers)
# 上一次跳转的地址
print(response.history)
# 返回cookie字典,返回cookies对象
# 获取cookies信息
print(response.cookies)
# 获取cookies信息转换成字典
print(response.cookies.get_dic())
# 获取cookies信息转换成字典
print(response.cookies.items())
# 字符编码
print(response.encoding)
response.encoding='utf-8'
print(response.elapsed)
# 生成器
# 往音频地址发送get请求
import requests
# https=http+ssl(携带安全认证证书)
# ssl是全世界的安全认证中心
requests.get(url='https://xiaohuar.com',verify=True) # 方法一:True 代表携带证书
print()
# 超时设置
import requests
response=requests.get('https://www.baidu.com/',timeout=0.1)
print(response.status_code)
# 代理使用
# 伪代码
import requests
proxies={
# 带用户名密码的代理,@符号前是用户名与密码
'http':'http://tank:123@localhost:9527',
'http':'http://localhost:9527',
'https':'https://localhost:9527',
}
response=requests.get('https://www.12306.cn',
proxies=proxies)
print(response.status_code)
# 免费代理西刺代理
# http://ipip.net
# 花生代理
# 加密方式与用户体验是挂钩的
# 认证方式
#
# 6.上传文件
import requests
# 上传文本文件
files1 = {'file': open('user.txt', 'rb')}
response = requests.post('http://httpbin.org/post', files=files1)
print(response.status_code) # 200
print(response.text) # 200
#
# 上传图片文件
files2 = {'jpg': open('35mm-aerial-aerial-shot-1105766.jpg', 'rb')}
response = requests.post('http://httpbin.org/post', files=files2)
print(response.status_code) # 200
print(response.text) # 200
3.selenium模块
超级无敌好用,用来模拟人操作浏览器
selenium模块讲解
一、什么是selenium
最初是一个自动化测试工具,selenium会模拟浏览器以及人的行为帮我们
给网站发送JS请求,跳过登录方式
request不可以自动执行JS代码
浏览器会帮我们的再次发送异步请求自动执行JS代码
二、为什么要使用?
1.优点:
使用requests模块登录需要分析大量的复杂通信流程,使用selenium可以轻松跳过登录验证
2.缺点:
要驱动浏览器,浏览器会加载css,js,图片。。数据等所有的代码,会使得爬取效率低。
三、如何使用
1.首先需要下载selenium模块,方法和下载requests模块相同
在命令行中输入:pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple selenium
2.下载驱动器
'''
#selenium第一次
# webdriver是用来驱动浏览器的
# from selenium.webdriver import ActionChains 调用得到一个动作链对象,破解滑动验证码的时候用的,可以拖动图片
from selenium import webdriver # 用来驱动浏览器的
from selenium.webdriver import ActionChains # 破解滑动验证码的时候用的 可以拖动图片
from selenium.webdriver.common.by import By # 按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys # 键盘按键操作
from selenium.webdriver.support import expected_conditions as EC # 和下面WebDriverWait一起用的
from selenium.webdriver.support.wait import WebDriverWait # 等待页面加载某些元素
from selenium import webdriver
import time
# 通过谷歌浏览器驱动打开谷歌浏览器
# 绝对路径有可能有.exe,有可能没有
# 驱动浏览器的一种方式
chrome=webdriver.Chrome(r'D:\360安全浏览器下载\chromedriver_win32\chromedriver')
# 驱动浏览器的另一种方式,将chromedriver.exe放入到python解释器的scipt文件中,;之后还要进行环境变量的配置。
# 往博客园主页发送get请求
try:
# chrome.get('https://www.cnblogs.com/')
# 访问百度
# chrome是一个驱动对象,里面包含其他函数
# 参数1:驱动对象。参数2:等待
wait=WebDriverWait(chrome,10)
chrome.get('https://www.baidu.com/')
# 查找input输入框
#!!!!!!注意!!!!!EC.presence_of_element_located((By.ID,"kw"))里面是写的元组,
#参数1.查找属性的方式,参数2:属性的名字
input_tag=wait.until(EC.presence_of_element_located((By.ID,"kw")))# kw是id的属性
# 3.搜索一拳超人
input_tag.send_keys('一拳超人')
# 4.按键盘回车键
input_tag.send_keys(Keys.EQUALS)
time.sleep(20)
# 无论发生什么异常都会关闭浏览器
finally:
# 关闭浏览器
chrome.close()
4.selenium之基本选择器
注意:所找属性要是唯一的,一般来说首选id
from selenium import webdriver # 用来驱动浏览器的
import time
# 获取驱动对象
driver=webdriver.Chrome()
try:
# 显示等待:等待某个元素加载
# 参数1:驱动对象,参数2:等待时间
# wait=WebDriverWait(chrome,10)
driver.get('https://china.nba.com/')
# 隐式等待:等待页面所有元素加载完成
# 等待加载完成后,从加载好的标签里查找,每次查找会等待10秒,如果找不到就下一个
driver.implicitly_wait(10)
news_tag=driver.find_element_by_class_name('nav-news')
print(news_tag)
time.sleep(10)
finally:
driver.close()
'''
===============所有方法===================
element是查找一个标签
elements是查找所有标签
1、find_element_by_link_text 通过链接文本去找
2、find_element_by_id 通过id去找
3、find_element_by_class_name
4、find_element_by_partial_link_text
5、find_element_by_name
6、find_element_by_css_selector
7、find_element_by_tag_name
'''
# 1.以文本作为标识
try:
# 显示等待:等待某个元素加载
# 参数1:驱动对象,参数2:等待时间
# wait=WebDriverWait(chrome,10)
driver.get('https://baidu.com/')
driver.implicitly_wait(10)
send_tag=driver.find_element_by_link_text('登录')
send_tag.click()
# 隐式等待:等待页面所有元素加载完成
# 等待加载完成后,从加载好的标签里查找,每次查找会等待10秒,如果找不到就下一个
finally:
driver.close()
# 2.通过局部文本查找标识
try:
# 显示等待:等待某个元素加载
# 参数1:驱动对象,参数2:等待时间
# wait=WebDriverWait(chrome,10)
driver.get('https://baidu.com/')
driver.implicitly_wait(10)
login_button = driver.find_element_by_partial_link_text('登')
login_button.click()
# 隐式等待:等待页面所有元素加载完成
# 等待加载完成后,从加载好的标签里查找,每次查找会等待10秒,如果找不到就下一个
finally:
driver.close()
# 3.通过class来找
try:
# 显示等待:等待某个元素加载
# 参数1:驱动对象,参数2:等待时间
# wait=WebDriverWait(chrome,10)
driver.get('https://baidu.com/')
driver.implicitly_wait(10)
login_tag1 = driver.find_element_by_class_name('tang-pass-footerBarULogin')
login_button.click()
time.sleep(1)
# 隐式等待:等待页面所有元素加载完成
# 等待加载完成后,从加载好的标签里查找,每次查找会等待10秒,如果找不到就下一个
finally:
driver.close()
# 4.通过name属性名查找
try:
driver.get('https://baidu.com/')
driver.implicitly_wait(10)
username = driver.find_element_by_class_name('useName')
username.send_keys('*******')
time.sleep(1)
finally:
driver.close()
# 5.通过id属性查找
try:
driver.get('https://baidu.com/')
driver.implicitly_wait(10)
username = driver.find_element_by_class_name('useName')
username.send_keys('*******')
time.sleep(1)
finally:
driver.close()
# 6.通过属性选择器查找
try:
driver.get('https://baidu.com/')
driver.implicitly_wait(10)
login_submit = driver.find_element_by_css_selector('#TANGRAM__PSP_10__submit')
# driver.find_element_by_css_selector('.pass-button-submit')
login_submit.click()
time.sleep(1)
finally:
driver.close()
# 7、find_element_by_tag_name 根据标签名称查找标签
try:
driver.get('https://baidu.com/')
driver.implicitly_wait(10)
div = driver.find_element_by_tag_name('div')
print(div.tag_name)
time.sleep(1)
finally:
driver.close()
5.京东实例
# 标签中首选id
# 目的就是查找唯一的属性,来定位
from selenium import webdriver # 用来驱动浏览器的
from selenium.webdriver import ActionChains # 破解滑动验证码的时候用的 可以拖动图片
from selenium.webdriver.common.by import By # 按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys # 键盘按键操作
from selenium.webdriver.support import expected_conditions as EC # 和下面WebDriverWait一起用的
from selenium.webdriver.support.wait import WebDriverWait # 等待页面加载某些元素
from selenium import webdriver
import time
# 通过谷歌浏览器驱动打开谷歌浏览器
# 绝对路径有可能有.exe,有可能没有
# 驱动浏览器的一种方式
chrome=webdriver.Chrome(r'D:\360安全浏览器下载\chromedriver_win32\chromedriver')
# 驱动浏览器的另一种方式,将chromedriver.exe放入到python解释器的scipt文件中,;之后还要进行环境变量的配置。
# 往博客园主页发送get请求
try:
# chrome.get('https://www.cnblogs.com/')