您现在的位置是:亿华云 > 人工智能
反爬篇 | 手把手教你处理 JS 逆向之 CSS 偏移
亿华云2025-10-02 14:51:20【人工智能】6人已围观
简介本篇文章将聊聊另外一种常见的反爬方案,即:「 CSS 偏移 」。CSS 偏移反爬是利用「 CSS 样式 」对网页元素进行一次自定义的排序,最后让网页以正确的数据展示出来。下面我们通过一个简单的实例,讲
本篇文章将聊聊另外一种常见的反爬反爬方案,即:「 CSS 偏移 」。篇手S偏
CSS 偏移反爬是把手利用「 CSS 样式 」对网页元素进行一次自定义的排序,最后让网页以正确的教处数据展示出来。
下面我们通过一个简单的反爬实例,讲解应对 CSS 偏移网站常规解决方案。篇手S偏
目标对象:aHR0cDovL3d3dy5wb3J0ZXJzLnZpcC9jb25mdXNpb24vZmxpZ2h0Lmh0bWw=
1.分析一下打开目标网站,把手在开发者工具面板中查看「 机票价格 」的教处网页元素组成方式。
我们发现,反爬机票价格由上、篇手S偏下两个区域的把手数据元素,通过一定的教处偏移量偏移,最后在页面上展示的反爬。
以第 1 条数据为例,篇手S偏机票实际价格为 467。把手
区域一宽度设置为 48px,left 的值为 -48px 代表左边距向左偏移 48px。
其内部的 i 标签宽度都为 16px,完全占满了父容器的宽度。
即:如果区域二隐藏的话,机票价格应该为 777。云服务器
我们继续看区域二的内容
第一个 b 标签,内容为 6,left 属性值为 -32px,宽度为 16px,会覆盖上面的第二个数字。
第二个 b 标签,内容为 4,left 属性值为 -48px,宽度同样为 16px,会覆盖掉上面的第一个数字。
因此,最后网页展示的机票价格就是 467。
2.特殊处理如果仔细观察网页元素,会发现 b 元素下的第三个 i 标签既然展示在第二个行,而不是和前面两个 i 标签在同一行展示。
其实,这是因为 i 元素标签设置样式 display 为 inline-block。
PS:inline-block 默认元素之间会存在一定的间隙。
因此,为了正确解析出数据,我们需要针对网页源代码对部分网页元素进行二次更新。
3.实战一下首先,我们需要安装依赖包。
# 依赖包
# bs4 用于对网页源码的服务器租用元素样式进行二次更新
pip3 install beautifulsoup4
# lxml 用于爬取网页数据
pip3 install lxml接下来,我们使用 bs4 解析网页源码,获取所有的 em 元素,修改它下面「 b 标签 」的 display 属性值为浮动「 flex 」,然后重新导出数据。
import requests
from bs4 import BeautifulSoup
...
url = http://.../flight.html
resp = requests.get(url).text
# 首次解析源码
soup = BeautifulSoup(resp, "lxml")
# 查询页面中的em元素
em_elements = soup.find_all("em", class_="rel")
# 对第一个b标签添加flex的属性
for em_element in em_elements:
first_b_element = em_element.find_all(b)[0]
# 添加flex属性
first_b_element[style] = first_b_element[style] + ;display:flex;
# 重新导出进行数据解析
resp = soup.prettify()
...
# 写入到本地文件查看
# with open(temp.html, w, encoding=utf-8) as file:
# file.write(resp)
...紧接着,我们利用 xpath 语法获取所有航班 Item 元素控件。
结合正则表达式拿到机票价格对应元素的 left 偏移量,通过这个偏移量可以计算出数据应该展示的位置索引。
最后,根据索引将数据放置在列表的既定位置,组成真实的机票价格。
import re
from lxml import etree
...
# 数据解析
html = etree.HTML(resp)
# 查询有几个航班数据
div_list = html.xpath(//div[@class="left col-md-9"]/div)
print(航班数据数目:, len(div_list))
for index in range(len(div_list)):
# 获取所有b标签
b_elements = div_list[index].xpath(.//em/b)
# 从第1个b标签下面的子标签数据 ,这样就可以获取价格的位数(3位、4位)
price_num_list = b_elements[0].xpath(./i/text())
print("打底机票价格为:", .join([item.strip() for item in price_num_list]))
# 从第2个b标签开始,获取真实价格对应的数字
for index, b_element in enumerate(b_elements[1:]):
# 数据
price_num = int(b_element.xpath(./text())[0])
# 获取b标签的style属性值
style = b_element.xpath(./@style)[0]
# 利用正则表达式,获取left属性值
left_value = re.findall(left:(.*?)px, style)[0]
# 根据left值,计算数据在真实价格中的索引位置(-1/-2/-3)
price_index = int(int(left_value) / 16)
# 替换源数组中的数据,按索引将数值设置进去
price_num_list[price_index] = price_num
# item都转成字符串,高防服务器合成一个新的数组
price_num_list = [str(item).strip() for item in price_num_list]
# 组成价格
price = int(.join(price_num_list))
print("机票价格:", price)
...很赞哦!(12314)
相关文章
- 成功管理和保护数据的三种方法
- 4.域名的整体品牌营销力
- 前面这两个步骤都是在本机完成的。到这里还没有涉及真正的域名解析服务器,如果在本机中仍然无法完成域名的解析,就会真正请求域名服务器来解析这个域名了。
- 如果你的潜在终端必须是这个米(域名),那么潜在终端并不多,也没有硬通货,那么你的域名应该在终端有兴趣购买时出售。否则,你可能得自己留着吃。
- 如何为可持续的未来建设节能数据中心?
- 4、注册门槛低
- 小白注册网站域名该怎么办?有什么步骤?
- 解析之后一般在十分钟内生效,如果没有生效可以联系域名服务商进行沟通。
- 超聚变发布FusionPoD 和全新一代FusionServer V7服务器
- 3、商标域名一经注册,就可以作为域名裁决过程中的主要信息之一。这可以大大增加公司被抢注的相关域名胜诉的机会。
热门文章
- 新华三李立:攻关算网新技术,推动算力均衡发展
- 其次,一般域名注册有一个获取密码的按钮,域名注册商点击后会向您发送密码。在得到域名注册商发送的密码后,将其传输到域名服务提供商网站,然后输入密码,此时域名呈现申请状态。提交申请后,原注册人通常会向您发送一封电子邮件,询问您是否同意转让。此时,您只需点击同意转移按钮,域名注册商就可以成功转移。
- 域名资源有限,好域名更是有限,但机会随时都有,这取决于我们能否抓住机会。一般观点认为,国内域名注册太深,建议优先考虑外国注册人。外国注册人相对诚实,但价格差别很大,从几美元到几十美元不等。域名投资者应抓住机遇,尽早注册国外域名。
- 3、商标域名一经注册,就可以作为域名裁决过程中的主要信息之一。这可以大大增加公司被抢注的相关域名胜诉的机会。
站长推荐
数据中心到底是如何工作的?
2016年1月1日:注册价格将降至每年7欧元。
3、考虑出售域名
tk域名是什么域名?新手对tk域名有什么看法?
九个优秀开源数据中心基础设施管理(DCIM)工具
域后缀首选.com,.net,然后是.cn。后缀选择不当,导致流量损失。域名是企业与互联网网址之间的链接,关键是企业在网络上存在的标志。因此,选择好域名是开展网上工作的首要重要条件。
顶级域名可以增加企业品牌的价值。随着经济的快速发展,域名已不再是企业在网络中的独立地位。顶级域名的服务范围、企业产品、综合形象体现等,对于企业单位来说,顶级域名的重要性不言而喻。
在更换域名后,并不是就万事大吉了,我们需要将旧域名做301重定向到新域名上,转移旧域名的权重到新域名上。