1.Requests
模块:
Requests
是用Python语言编写,基于urllib
,采用 Apache2 Licensed
开源协议的 HTTP
库,它比urllib
更加的方便,可以节约我们大量的工作,完全满足 HTTP
测试需求
Requests
的哲学是以 PEP 20
(一种标准规范)的习语为中心开发的,所以它比urllib
更加简洁
(1)Requests
模块的安装:
Requests
是Python语言的第三方库,专门用于发送HTTP
请求
安装方式:
#1.在终端输入
pip install requests
#2.换源安装:若出现下载超时,过慢的情况,换源即可
# 示例
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 阿里云 http://mirrors.aliyun.com/pypi/simple/
# 豆瓣http://pypi.douban.com/simple/
# 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
# 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
# 华中科技大学http://pypi.hustunique.com/
(2)Requests
的使用:
1.常用方法:
requests.get("网址")
request.post("网址")
2.常用参数:
url
:url
地址,接口文档标注的接口请求地址
params
:请求数据中的链接,常见的一个get请求,请求参数都是在url
地址中
data
:请求数据,参数是表单的数据格式
json
:接口常见的数据请求格式
headers
:请求头信息
cookie
:保存的用户登录信息,比如做一些充值功能,但是需要用户已经登录,需要cookie
信息的请求信息传输
#推荐一个爬虫工具:爬虫工具库
# https://spidertools.cn/#/curl2Request
3.响应内容:
r.encoding
:获取当前的编码
r.encoding = 'charset'
:设置编码格式,多为'utf-8'
编码
r.text
:以encoding
解析返回内容。字符串方式的响应体,会自动根据响应头部的字体编码进行解码
r.cookies
:返回cookie
r.headers
:请求头,以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None
r.status_code
:响应状态码
r.json()
:Requests
中内置的JSON
解码器,以json
形式返回,前提返回的内容确保是json
格式的,不然解析出错会抛出异常
r.content
:字节流,以字节形式(二进制)返回,字节方式的响应体,会自动为你解码gzip
和deflate
压缩
4.Requests
中get
请求之参数应用 -- 搜狗搜索海贼王案例:
(1)把参数添加到url
链接中 -- 平民写法(用到的最多的写法)
#导入模块
import requests
#目标url
url = 'https://www.sogou.com/web?query=%E6%B5%B7%E8%B4%BC%E7%8E%8B&_asf=www.sogou.com&_ast=&w=01015002&p=40040108&ie=utf8&from=index-nologin&s_from=index&oq=&ri=0&sourceid=sugg&suguuid=&sut=0&sst0=1678439364372&lkt=0%2C0%2C0&sugsuv=1666847250696567&sugtime=1678439364372'
#请求头部信息
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
'Cookie':'ABTEST=8|1701776265|v17; SNUID=7B0346FA646568A5CDB26F5B64A6691E; IPLOC=CN3205; SUID=186722991B5B8C0A00000000656F0B89; cuid=AAFqAmPwSAAAAAqMFCnulgEASQU=; SUV=1701776266958330; browerV=3; osV=1; sst0=372'
}
#发起请求
response = requests.get(url, headers=headers)
#指定编码格式
response.encoding = 'utf-8'
#获取响应
html = response.text
#文件写入响应数据内容
with open("海贼王1.html","w",encoding='utf-8') as i:
i.write(html)
#打印响应(数据)内容
print(html)
注意: 1.值与值之间需要用逗号隔开
(2)把参数添加到params
中 -- 官方写法(不常用)
#导入模块
import requests
#请求头部信息 -- 字典的形式
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
#cookie的两种设置方式
#(1)'Cookie':'ABTEST=8|1701776265|v17; SNUID=7B0346FA646568A5CDB26F5B64A6691E; IPLOC=CN3205; SUID=186722991B5B8C0A00000000656F0B89; cuid=AAFqAmPwSAAAAAqMFCnulgEASQU=; SUV=1701776266958330; browerV=3; osV=1; sst0=372'
}
#cookie值 -- (2)字典的形式
cookies = {
"ABTEST": "8^|1701776265^|v17",
"SNUID": "7B0346FA646568A5CDB26F5B64A6691E",
"IPLOC": "CN3205",
"SUID": "186722991B5B8C0A00000000656F0B89",
"cuid": "AAFqAmPwSAAAAAqMFCnulgEASQU=",
"SUV": "1701776266958330",
"browerV": "3",
"osV": "1",
"sst0": "372"
}
#目标url
url = "https://www.sogou.com/web"
#get请求所携带的参数
params = {
"query": "海贼王",
"_asf": "www.sogou.com",
"_ast": "",
"w": "01015002",
"p": "40040108",
"ie": "utf8",
"from": "index-nologin",
"s_from": "index",
"oq": "",
"ri": "0",
"sourceid": "sugg",
"suguuid": "",
"sut": "0",
"sst0": "1678439364372",
"lkt": "0^%^2C0^%^2C0",
"sugsuv": "1666847250696567",
"sugtime": "1678439364372"
}
response = requests.get(url, headers=headers, cookies=cookies, params=params) #因为cookie中不只有一个键值对所以要加s
print(response.text)
print(response)
#文件写入响应数据内容
with open("海贼王2.html","w",encoding='utf-8') as i:
i.write(response.text)
官方写法快速的写法:
1.进入目标
url
的页面进行如下操作:
>
2.进入爬虫工具库进行如下操作:
>
3.得到如下代码:
import requests headers = { "authority": "www.sogou.com", "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "max-age=0", "sec-ch-ua": "^\\^Google", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "^\\^Windows^^", "sec-fetch-dest": "document", "sec-fetch-mode": "navigate", "sec-fetch-site": "none", "sec-fetch-user": "?1", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36" } cookies = { "ABTEST": "8^|1701776265^|v17", "SNUID": "7B0346FA646568A5CDB26F5B64A6691E", "IPLOC": "CN3205", "SUID": "186722991B5B8C0A00000000656F0B89", "cuid": "AAFqAmPwSAAAAAqMFCnulgEASQU=", "SUV": "1701776266958330", "browerV": "3", "osV": "1", "sst0": "372" } url = "https://www.sogou.com/web" params = { "query": "^%^E6^%^B5^%^B7^%^E8^%^B4^%^BC^%^E7^%^8E^%^8B", "_asf": "www.sogou.com", "_ast": "", "w": "01015002", "p": "40040108", "ie": "utf8", "from": "index-nologin", "s_from": "index", "oq": "", "ri": "0", "sourceid": "sugg", "suguuid": "", "sut": "0", "sst0": "1678439364372", "lkt": "0^%^2C0^%^2C0", "sugsuv": "1666847250696567", "sugtime": "1678439364372" } response = requests.get(url, headers=headers, cookies=cookies, params=params) print(response.text) print(response)
注意: 1.官方写法不建议使用,因为它会把所有的参数都携带上,有些参数可能会有反爬
2.params
的数据类型为字典数据,必须满足键值对
5.如何快速将headers
中的参数匹配为字典数据(了解):
#使用正则替换
1.将 headers 中的参数内容全部选中
2.按住 CTRL + R 键:会弹出一个提示框
3.在第一行输入正则语法:(.*):\s(.*)$
4.在第二行输入正则语法:"$1":"$2",
5.勾选 regax
6.点击 Replace All
注意: 1.因为已经有爬虫工具库了,所以这个方法也就用不上了,大家当作拓展就好
2.写的时候注意语法不要写错,特别是第二行的正则语法后面的英文逗号,一定要加
正则替换法的操作图示:
>
6.Requests
中post
请求:
post
请求的大多数用法和get
请求一样,只是需要加上data
参数
post
方法的使用场景:
1.网页需要登录的情况下
2.需要给网页传输内容的情况下
语法格式:
response = requests.post("网址", data = data,headers=headers)
360翻译示例:
#导入模块
import requests
#目标url
'''
url分析 -- 实现英文翻译成中文:
https://fanyi.so.com/index/search?eng=1&validate=&ignore_trans=0&query=love
https://fanyi.so.com/index/search?eng=1&validate=&ignore_trans=0&query=like
https://fanyi.so.com/index/search?eng=1&validate=&ignore_trans=0&query=enjoy
根据多个英文翻译的url分析,发现改变的只有单词不同,其余的内容完全一致,也就是说我们可以把最后面单词的位置设置成一个变量,这样的话就可以实现单词翻译,
而不是想翻译一个单词就去改变一下它的url
'''
'''
url分析 -- 实现中文翻译成英文:
https://fanyi.so.com/index/search?eng=0&validate=&ignore_trans=0&query=%E7%88%B1%E6%83%85
https://fanyi.so.com/index/search?eng=0&validate=&ignore_trans=0&query=%E5%96%9C%E6%AC%A2
https://fanyi.so.com/index/search?eng=0&validate=&ignore_trans=0&query=%E4%BA%AB%E5%8F%97
'''
'''
根据两种翻译的url分析,发现除结尾不同外其eng也不同,一个是0;一个是1
两种方法都实现的实现方法:
第一个方法: if判断
第二个方法: 函数
'''
print("中文 --> 英文 ; 点击0")
print("英文 --> 中文 ; 点击1")
choose = input("请输入你的选择: ")
word = input("请输入你想翻译的内容: ")
url = f'https://fanyi.so.com/index/search?eng={choose}&validate=&ignore_trans=0&query={word}'
#请求头信息
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
'Pro':'fanyi' # 查看后发现在这个参数中做了反爬,所以这个参数必须要加上
}
#post请求要携带的参数
data = {
'eng': f'{choose}', # 注意改变参数,因为url中的eng参数已经被我们设置成了choose变量
'validate': "",
'ignore_trans': '0',
'query': f'{word}' # 注意改变参数,因为url中的最后一项参数已经被我们设置成了word变量
}
#发起请求
response = requests.post(url,headers = headers,data = data)
'''
#检测可能出现的错误
print(response.text) #经过检测后发现没有报错,data不可能有问题,所以只能是在其它地方出现反爬
'''
'''
#获取响应数据
result = response.json() #报出 JSONDecodeError 错误,说明response并不能满足转换成json对象
print(result)
'''
'''
#获取响应数据
result = response.json()
print(result)
'''
#获取响应数据
result = response.json()
#信息过滤
fanyi = result['data']['fanyi'] #字典取值
'''
字典取值的两种方法:
1.['key'] -- 取不到值会报错【
2.xxx.get('key') -- 取不到值会返回None
注意:一旦取不到值对于第一种方法需要进行异常处理,而第二种方法则不用去管
'''
print(fanyi)
信息过滤图示:
重放请求:(以360翻译为示例进行图示讲解)
通过重放请求来寻找反爬参数:
(1)
(2)
(3)
(4)
(5)
(6)
(7)
注意:
当删除的是非反爬参数时,我们会发现它并不影响正常的运行,所以只有删除的是反爬参数的时候,才会影响到正常的运行
2.Cookie
与Session
实战:
在浏览网站的过程中,我们经常会遇到需要登录的情况,有些页面只有登录之后才可以访问。在登录之后可以连续访问很多次网站,但是有时候过一段时间就需要重新登录。还有一些网站,在打开浏览器时就自动登录了,而且在很长时间内都不会失效,这里面所涉及的就是 Session
和 Cookie
的相关知识
(1)Cookie
通过在客户端记录的信息确定用户身份
HTTP是一种无连接协议,客户端和服务器交互仅仅限于请求 / 响应过程,结束后断开,下一次请求时,服务器会认为是一个新的客户端,为了维护他们之间的连接,让服务器知道这是前一个用户发起的请求,就必须在一个地方保存客户端信息
(2)Session
Session
,中文称之为会话,通过在服务端记录的信息确定用户身份,其本义是指有始有终的一系列动作。例如打电话时,从拿起电话拨号到挂断电话之间的一系列过程就可以称为一个 Session
爬虫图解
Cookie
与Session
-- 登录流程:文字解析:
1.再次登录其实就是验证之前生成的账号和密码,从数据库中去查询当前的用户是否存在,若存在就是登录成功了,然后通过加密算法返回session_id
2.set_cookie
是服务器返回的,因为只有服务器返回的才是set_cookie
3.服务端根据cookie
中携带的session_id
去名为session
的数据库(假设session_id
存储在名为session
的数据库中)中找session_id
是否存在
4.这样做的好处就是用户只需要输入一次账号和密码,之后在访问网页时,只需要在headers
信息利用Cookie
包含session_id
,后台就可以根据session_id
来判断用户是否登录
Cookie与Session实战案例 -- 12306查票示例:
import requests
headers = {
"Accept": "*/*",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"If-Modified-Since": "0",
"Pragma": "no-cache",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
"sec-ch-ua": "^\\^Google",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "^\\^Windows^^"
}
cookies = {
"_uab_collina": "170210568210505922888592",
"JSESSIONID": "749E316CAE2341138F39924F8E156F25",
"_jc_save_fromStation": "%u5317%u4EAC%2CBJP",
"_jc_save_wfdc_flag": "dc",
"BIGipServerotn": "3788964106.64545.0000",
"BIGipServerpassport": "837288202.50215.0000",
"guidesStatus": "off",
"highContrastMode": "defaltMode",
"cursorStatus": "off",
"route": "495c805987d0f5c8c84b14f60212447d",
"_jc_save_fromDate": "2024-06-26",
"_jc_save_toDate": "2024-06-26",
"_jc_save_toStation": "%u6210%u90FD%2CCDW"
}
url = "https://kyfw.12306.cn/otn/leftTicket/query"
params = {
"leftTicketDTO.train_date": "2024-06-26",
"leftTicketDTO.from_station": "BJP",
"leftTicketDTO.to_station": "CDW",
"purpose_codes": "ADULT"
}
response = requests.get(url, headers=headers, cookies=cookies, params=params)
data = response.json()
# print(data,type(data))
result = data['data']['result']
# print(result,type(result))
for item in result: # item代表每一个车次数据
# print(item,"此时是字符串")
data_li = item.split('|') # 代表每一车次的杂乱数据
# print(data_li,"此时是列表")
# for i,f in enumerate(data_li): # 这个for循环是为了确定一等做和车次的索引
# pass
# print(i,f) # 通过 '|' 分割,拿到每一个杂乱小数据的索引值与具体的值
'''
车次 -- 索引为3
一等座 -- 索引为31
'''
if data_li[31] != "无" and data_li[31] != "":
print(data_li[3], "有票", "一等座剩余:", data_li[31])
else:
print(data_li[3], "无票")
注意: 代码失效可能是因为cookies
或url
或params
等需要更新替换