整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

「UI设计」web页面中的br加密问题

题背景

如下是豆瓣的电影页面,这次练习就是为了进行数据处理的beautifulsoup和pyquery的处理练习

本次练习主要是针对beautifulsoup和pyquery的两个解析库的使用,但在实际上的content获取的时候就出错了,在准备过程中,为了比较完整模拟浏览器获取,所以构造了如下请求头:

header = {
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding':'gzip, deflate, sdch, br',
    'Accept-Language':'zh-CN,zh;q=0.8',
    'User-Agent': 'Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A101a Safari/419.3'
}

针对上面请求头,进行代码编辑如下:

from urllib import error
import requests
from loguru import logger


BASE_URL = 'https://movie.douban.com/'
requests.DEFAULT_RETRIES = 3
header = {
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding':'gzip, deflate, sdch, br',
    'Accept-Language':'zh-CN,zh;q=0.8',
    'User-Agent': 'Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A101a Safari/419.3'
}


def scrapy_index():
    try:
        header['User-Agent'] = next(random_agent())
        logger.info(header)
        res = requests.get(BASE_URL, headers=header)
        if res.status_code == 200:
            logger.info(f'准备爬取豆瓣上正在上映电影信息:{res.url}')
            logger.info(res.reason)
            with open('content.html', 'wb') as f:
                f.write(res.content)
            with open('text.html', 'w') as f:
                f.write(res.text)
    except error.URLError as err:
        logger.error(err.reason)
    except error.HTTPError as err:
        logger.error(err.reason)
    except Exception as err:
        logger.error(traceback.print_exc())


if __name__ == '__main__':
    scrapy_index()

如上是简单请求代码,只针对请求后content和text的源码保存,保存后源码片段如下:

��@�_��?�z��,i�K�3~{,.�Ѣ��0��Ab��Cg!ݷ��
�Q�u�2F�����ۙ?wUw�Ο�dV*B#%f).�a��d�<���:��1̬m���z|�̶m�_�������Rp:g�
D��[
�ϰ̒�C�s����?�"����������(�D���{���΢�?��XL��[���������������������oK�q��������?K7���8c����<�9�����Mw�a�f�
\�D�o5̠Q�\���'*�̠�"�Y����2�!�T��]���Ә����Q��&.�����z��1|�Hz��?��K����E��
3����/�aK�9N!�Lߌ�k���isO��ŋ+��T9��Y�����ґБJ�?�4�
i�

因为源码较长,所以只是进行缩略版的展示,一开始还以为是wasm的一个支持,所以在浏览器上f12看了一下,但又不是这个类型的,回归请求头,一个一个字段进行注释,然后请求来排除,比对结果,发现排除了Accept-Encoding的影响,结果就能得到往常需要的比较正经的html源码了。

深入了解一下Accept-Encoding

Accept-Encoding是想浏览器的骑牛,表示客户端支持的编码类型,如下就有gzip, deflate, sdch, br几种类型,这里的数据获取,用的是requests,而请求后的响应response.content会自动解码gzip和deflate类型为bytes类型数据,response.text会根据头部编码格式来解码成str类型的数据,但,这里,不支持br类型!!!

br是Brotli的加解密算法,要进行这个类型的页面解析,需要使用brotli包,如下:

pip install brotli

然后修改一下,大致如下就行:

def scrapy_index():
    try:
        header['User-Agent'] = next(random_agent())
        logger.info(header)
        res = requests.get(BASE_URL, headers=header)
        if res.status_code == 200:
            logger.info(f'准备爬取豆瓣上正在上映电影信息:{res.url}')
            content, text = res.content, res.text
            if res.headers['Content-Encoding'] == 'br':
                content = brotli.decompress(content)
                text = brotli.decompress(text)
            with open('content.html', 'wb') as f:
                f.write(content)
            with open('text.html', 'w') as f:
                f.write(text)

嗯,理论上是这样,然后就能实现解码后的源码获取了,content和text都是一样的源码,只是数据类型不一样而已,前者是bytes类型后者是str类型。不过意外的是,br后传过来的content却不是之前的加密后数据了,嗯,应该是笔者完整代码中的user-Agent随机生成的不一样,所以得到的结果有点随机。

另外的解决办法

比较简单,把br的编码方式注释掉就行。

、动态生成的html,样式不生效

//html 布局
<view v-html="html">
  {{html}}
 </view>

//动态生成的元素
<view class="btngo" @tap="handleLink(`${ajaxlink}`)" >
  去报名
</view>	
//然后scoped的.btngo不生效,因为v-html创建的DOM内容不受作用域内的样式影响,
//于是我们仍然可以通过深度作用选择器来为他们设置样式。
::v-deep {
  .btngo{
    display: inline-block;
    width: 200px;
    height: 44px;
    line-height: 44px;
    background-image: linear-gradient(180deg, #62AFFF 0%, #007BFF 100%);
  }
}

2、动态生成的html,点击事件不生效

让我醍醐灌顶的两种解决方法,我选择了第2种。

  • 1、使用事件委托
  • 2、绑定到外面不动态的元素上等着事件触发

TML标签

基本标签

HTML页面中内容是由HTML标签组织起来的,如页面中的文本、图像、Flash视频文件等都是通过HTML标签合理地显示在页面的各个位置。



1 标题标签<h1>~<h6>

标题标签表示一段文字的标题(主题),并且支持多层次的内容结构。HTNL.共提供了6级标题,分别为<h1>~<h6>,并赋予了标题一定的外观,所有标题字体加粗,其中山<h1>字号最大,<h6>字号最小.


2.图像标签<img>

在网页中常用的图像格式有4种,即JPG、GIF、BMP.PNG,其中使用比较多的是JPG、GIF和PNG,大多数浏览器都可以显示这些图像。


显示图像的语法:

< img src="ur1" alt="文本" width="x" height="y"/>


在语法中:

a、SrC属性:表示显示图像的地址。

b、alt属性:指定图像的替代文本,当图像无法显示时(如图片路径错误或网速太慢等)替代显示的文本,这样,即使图像无法显示,用户还可以看到网页丢失的信息,所以为页面上的图像都加上替换文本属性是个好习惯,这样有助于更好地显示信息,并且对于那些使用纯文本浏览器的人来说是非常有帮助的。

c、width属性:表示图像宽度.

d、height属性:表示图像高度。


3.段落标签<p>

顾名思义,段落标签表示将一段文字组成一系列段落内容,这样做的目的是内容应用某些格式和布局,使各个段落的逻辑更清晰明了。在HTML文档中,段落通过<p>标签定义。段落标签<p>表示段落的开始,</p >表示段落的结束。


4.换行标签<br/>

在希望不产生一个新段落的情况下进行换行,则使用<br>标签。<br>是一个空的HTML标签,由于关闭标签没有任何意义,因此它没有结束标签。


注意:

使用<b>和<br>的结果一样,在XHTML以及未来的HTML版本中,根据W3C规范,不允许使用没有结束标签的HTML元素,因此使用<br>页面更规范,有更长远的保障。


5.水平线标签<hr/>

水平线标签表示一条水平线,注意该标签与<br>标签一样,没有结束标签,直接使用<hr/>表示标签的开始和结束。

使用以上讲解的基本标签,就可以进行网页内容排版了。