前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python requests 一种通过编码的反爬虫机制

python requests 一种通过编码的反爬虫机制

作者头像
forxtz
发布2021-03-19 17:54:10
6440
发布2021-03-19 17:54:10
举报
文章被收录于专栏:源懒由码

  简介:遇到一个反爬虫机制,该网页为gbk编码网页,但是请求参数中,部分请求使用gbk编码,部分请求使用utf8编码,还设置了一些不进行编码的安全字符,在爬取的过程中形成了阻碍。

  提示:在认为参数设置正常,又无法正确爬取数据的情况下,通过response.requests.headers和esponse.requests.body与浏览器的请求数据的对比,会比较容易发现问题。

1.python的url编码函数

也有通用函数- decode(解码为unicode),encode(编码)

代码语言:javascript
复制
import requests  
from urllib.parse import urlencode  # 对整个字典进行编码
from requests.utils import quote,unquote  # 对字符串进行编码和解码
代码语言:javascript
复制
# 对整个字典进行编码,对于需要进行局部编码不太方便。
Signature:
urlencode(
    query,
    doseq=False,
    safe='',  # 不进行编码的字符串
    encoding=None,
    errors=None,
    quote_via=<function quote_plus at 0x0000027AB54DD678>,
)
Docstring:
Encode a dict or sequence of two-element tuples into a URL query string.

If any values in the query arg are sequences and doseq is true, each
sequence element is converted to a separate parameter.

If the query arg is a sequence of two-element tuples, the order of the
parameters in the output will match the order of parameters in the
input.

The components of a query arg may each be either a string or a bytes type.

The safe, encoding, and errors parameters are passed down to the function
specified by quote_via (encoding and errors only if a component is a str).
代码语言:javascript
复制
# 对字符串进行编码
Signature: requests.utils.quote(string, safe='/', encoding=None, errors=None)
Docstring:
quote('abc def') -> 'abc%20def'
代码语言:javascript
复制
# 对字符串进行解码
Signature: requests.utils.unquote(string, encoding='utf-8', errors='replace')
Docstring:
Replace %xx escapes by their single-character equivalent. The optional
encoding and errors parameters specify how to decode percent-encoded
sequences into Unicode characters, as accepted by the bytes.decode()
method.
By default, percent-encoded sequences are decoded with UTF-8, and invalid
sequences are replaced by a placeholder character.

unquote('abc%20def') -> 'abc def'.

2、模拟过程 - 以错误编码模式

这里还设置了一个安全符号,如果设置。"+"会进行编码。

代码语言:javascript
复制
# 如果错误的采用了网页编码进行访问
# 1. 请求数据
req1 = '+导出+++'
print('1.原始请求数据:',req1)
# 2. 自行编码以后发送出去的数据
req2 = quote(req1,encoding='gbk',safe='+')
print('2.浏览器编码后发出的数据:',req2)
# 3. 服务区接受的数据为req2,服务器会编码以后提交给后台
req3 = unquote(req2,encoding='gbk')
print('3.经服务器编码以后,后台接收到的数据:',req3)
# 4. 后台逆编码获取浏览器发送的原始数据
req4 = quote(req3,encoding='gbk',safe='+')
print('4.后台逆编码,重新得到浏览器发送的原始数据:',req4)
# 5. 后台再进行正确编码获取正确数据
req5 = unquote(req4,encoding='utf8')
print('5.后台逆编码,重新得到浏览器发送的原始数据,最终获取数据为乱码:',req5)

最后后台获取的数据是乱码,可以进行校准,如果是非正常编码数据则不进行处理。

代码语言:javascript
复制
1.原始请求数据: +导出+++
2.浏览器编码后发出的数据: +%B5%BC%B3%F6+++
3.经服务器编码以后,后台接收到的数据: +导出+++
4.后台逆编码,重新得到浏览器发送的原始数据: +%B5%BC%B3%F6+++
5.后台逆编码,重新得到浏览器发送的原始数据: +����+++

3、模拟过程-正确例子

代码语言:javascript
复制
# 1. 请求数据
req1 = '+导出+++'
print('1.原始请求数据:',req1)
# 2. 自行编码以后发送出去的数据
req2 = quote(req1,encoding='utf8',safe='+')
print('2.浏览器编码后发出的数据:',req2)
# 3. 服务区接受的数据为req2,服务器会编码以后提交给后台
req3 = unquote(req2,encoding='gbk')
print('3.经服务器编码以后,后台接收到的数据:',req3)
# 4. 后台逆编码获取浏览器发送的原始数据
req4 = quote(req3,encoding='gbk',safe='+')
print('4.后台逆编码,重新得到浏览器发送的原始数据:',req4)
# 5. 后台再进行正确编码获取正确数据
req5 = unquote(req4,encoding='utf8')
print('5.后台逆编码,重新得到浏览器发送的原始数据:',req5)
代码语言:javascript
复制
1.原始请求数据: +导出+++
2.浏览器编码后发出的数据: +%E5%AF%BC%E5%87%BA+++
3.经服务器编码以后,后台接收到的数据: +瀵煎嚭+++
4.后台逆编码,重新得到浏览器发送的原始数据: +%E5%AF%BC%E5%87%BA+++
5.后台逆编码,重新得到浏览器发送的原始数据: +导出+++
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档