python学习笔记及作业(post请求,request的高级用法,selenium)

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/')
    # 访问百度
    # chrome是一个驱动对象,里面包含其他函数
    # 参数1:驱动对象。参数2:等待
    wait=WebDriverWait(chrome,10)
    chrome.get('https://www.jd.com/')
    # 查找input输入框
    #!!!!!!注意!!!!!EC.presence_of_element_located((By.ID,"kw"))里面是写的元组,
    #参数1.查找属性的方式,参数2:属性的名字
    input_tag=wait.until(EC.presence_of_element_located((By.ID,"key")))#  kw是id的属性
    # 3.搜索一拳超人
    input_tag.send_keys('唐诗三百首')
    # 4.按键盘回车键
    search_button=wait.until(EC.presence_of_element_located((By.CLASS_NAME,"button")))
    search_button.click()
    time.sleep(20)
    # 无论发生什么异常都会关闭浏览器
finally:
    # 关闭浏览器
    chrome.close()

 

posted @ 2019-06-17 19:37  lhhhha  阅读(5623)  评论(0编辑  收藏  举报