JavaScript动态渲染页面爬取——CSS位置偏移反爬案例分析与爬取实战

CSS位置偏移反爬案例分析与爬取实战

  1. 案例

案例网址:https://antispider3.scrape.cener/,页面如下图所示:

Screenshot 2024-03-30 at 07.39.32

尝试用Selenium获取首页的页面源代码,并解析每个标题的内容:

from selenium import webdriver
from pyquery import PyQuery as pq
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.service import Service

options = webdriver.ChromeOptions()
services = Service('../Selenium/chromedriver')

browser = webdriver.Chrome(service=services, options=options)
browser.get('<https://antispider3.scrape.center/>')
WebDriverWait(browser, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.item')))

html = browser.page_source
doc = pq(html)
names = doc('.item .name')
for name in names.items():
    print(name.text())
browser.close()

运行结果如下:

Wonder
清 白 家 风
篇 法 妃 老 的 上 宠 终 册 ) ( 结 下
士 为 己 ) 二 册 知 全 (
, 些 年 们 一 孩 我 的 那 起 女 追
非 我 倾 城 ( 全 三 册 )
朝 事 儿 明 些 那
的 你 忘 和 书 笑 我
全 第 波 集 小 一 卷 王
怦 然 动 心
龙枪编年史(全3册)
龙 枪 册 全 奇 ( ) 三 传
黎 明 之 街
其 知 认 理 学 心 示 启 及
银河帝国2:基地与帝国
银 河 帝 国 : 基 地
级 下 材 全 教 学 - 年 解 语 文 四 小
越界言论(第3卷)

结果中很多标题的文字顺序是乱的,例如《明朝那些事儿》对应的输出结果是“朝事儿明些那”,这是怎么回事?

  1. 排查

我们去浏览器里面研究一下源代码,如图所示:

Screenshot 2024-03-29 at 21.05.21

发现一个字对应一个span节点,这个节点本身的顺序也是乱的,所以用pyquery提取出来的标题内容乱序就不足为怪了。

源代码中的文字本身是乱的,那为什么在网页上看到的标题是正确的?这是因为网页本身利用CSS控制了文字的偏移位置,什么意思呢?观察下源代码:

<h3 data-v-7f1a77ef="" class="m-b-sm name">
<span data-v-7f1a77ef="" class="char" style="left: 80px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 16px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 0px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 48px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 32px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 64px;"></span>
  </h3>

可以发现,每个span节点都有一个style属性,表示CSS样式,left的取值各不相同。另外,在浏览器中观察一下每个span节点的完整样式,如图所示:

Screenshot 2024-03-29 at 21.21.56

span节点还有两个额外的样式,是display: inline-block和position:absolute,或者比较重要,代表绝对定位,设置这个样式后,就可以通过修改left的值控制span节点在页面中的偏移位置了,例如left:0px代表不偏移;left:16px代表从左边算起向右偏移16像素,于是节点就到了右边。源代码中,“明”子的偏移量是0,“朝”字的偏移量是16像素,“那”字的偏移量是32像素,依此类推,最终标题的视觉效果就变成了“明朝那些事儿”。

  1. 爬取

了解了基本原理后,只需要获取每个span节点的style属性,提取出偏移值,然后排序就可以得到最终结果了。先实现基本的提取方法:

from selenium import webdriver
from pyquery import PyQuery as pq
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.service import Service
import re

def parse_name(name_html):
    chars = name_html('.char')
    items = []
    for char in chars.items():
        items.append({
            'text': char.text().strip(),
            'left': int(re.search('(\\d+)px', char.attr('style')).group(1))
        })
    items = sorted(items, key=lambda x:x['left'], reverse=False)
    return ''.join([item.get('text') for item in items])

options = webdriver.ChromeOptions()
services = Service('../chromedriver')

browser = webdriver.Chrome(service=services, options=options)
browser.get('<https://antisipder3.scrape.center/>')
WebDriverWait(browser, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.item')))
html = browser.page_source
doc = pq(html)
names = doc('.item .name')
for name_html in names.items():
    name = parse_name(name_html)
    print(name)
browser.close()

这里定义了一个parse_name方法,用来解析页面源代码得到最终的标题。它接收一个参数name_html,就是标题的HTML文本,类似这样:

<h3 data-v-7f1a77ef="" class="m-b-sm name">
<span data-v-7f1a77ef="" class="char" style="left: 80px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 16px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 0px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 48px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 32px;"></span>
<span data-v-7f1a77ef="" class="char" style="left: 64px;"></span>
  </h3>

在parse_name方法中,我们首先选取.char节点,将其赋值为chars变量,然后遍历chars变量,其中每个条目各自对应一个span节点,其内容类似于:

<span data-v-7f1a77ef="" class="char" style="left: 16px"></span>

在parse_name方法中,我们首先选取.char节点,将其赋值为chars变量,然后遍历chars变量, 其中每个条目各自对应一个span节点,其内容类似于:

<span data-v-7f1a77ef="" class="char" style="left: 16px"></span>

遍历过程中,提取了span节点的文本内容作为字典的text属性,还提取了style属性的内容,例如这里提取的是16px,并用正则表达式提取了其中的数值,这里是16,将其赋值为字典的left属性。

遍历结束后,items的结果类似下面这样:

[{'text': '些', 'left': 48}, {'text': '事', 'left': 64}, {'text': '儿', 'left': 80}, {'text': '那', 'left': 32}, {'text': '朝', 'left': 16}, {'text': '明', 'left': 0}]

面对这样的结果,怎么排序呢?直接调用sorted方法就行,它有两个参数,一个是key,用来指定根据什么排序,这里我们直接使用lambda表达式提取span节点的left属性,所以最终结果是根据left的值排序而得;另一个参数是reverse,用来指定排序方式,此处将其设置为False,表示从小到大排序。排序完的items变成了这样:

[{'text': '明', 'left': 0}, {'text': '朝', 'left': 16}, {'text': '那', 'left': 32}, {'text': '些', 'left': 48}, {'text': '事', 'left': 64}, {'text': '儿', 'left': 80}]

最后将其中的text值提取出来并拼接,就得到了最终结果:

清白家风
法老的宠妃终结篇(上下册)
士为知己(全二册)
那些年,我们一起追的女孩
非我倾城(全三册)
明朝那些事儿
我和你的笑忘书
王小波全集第一卷
怦然心动

龙枪传奇(全三册)
黎明之街
认知心理学及其启示

银河帝国:基地
小学教材全解-四年级语文下

更多体验可以在小蜜蜂AI获取,网址:https://zglg.work

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/503877.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++中浅拷贝和深拷贝对象复制概念

1.浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a; 浅拷贝是指在对象复制时&#xff0c;只是复制对象的值&#xff0c;而不会复制对象指向的资源。这意味着对象和其副本会指向同一块内存空间&#xff0c;当一个对象改变时&#xff0c;另一个对象也会受到影响。 #inclu…

算法题->移动零的C语言和JAVA的双指针解法

使用C语言和JAVA代码通过双指针进行解题 题目描述:给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 理解题意:不改变数组中非零元素的顺序,并把0元素放在非零元素后面. 链接: https://leetcode.cn/problems/m…

光明源@智慧厕所公厕软件系统有哪些核心功能?

在现代城市的建设中&#xff0c;智慧公厕的建设成为了提升城市品质和居民生活质量的重要举措。而智慧公厕的核心&#xff0c;不仅仅在于其硬件设备的智能化&#xff0c;同样重要的是其背后支持的智慧厕所公厕软件系统。让我们一起探讨&#xff0c;智慧厕所公厕软件系统有哪些核…

上位机图像处理和嵌入式模块部署(qmacvisual图像拼接)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 qmacvisual本身提供了图像拼接的功能。功能本身比较有意思的。大家如果拍过毕业照&#xff0c;特别是那种几百人、上千人的合照&#xff0c;应该就…

了解 LoadRunner 性能测试软件及其基础使用

目录 一、了解LoadRunner 1、什么是Loadrunner&#xff1f; 2、Loadrunner包括什么组件&#xff1f; &#xff08;1&#xff09;前台组件 &#xff08;2&#xff09;后台组件 二、LoadRunner三大组件 1、VuGen&#xff08;虚拟用户脚本生成器&#xff09; &#xff08;…

Go 之 Gin 框架

Gin 是一个 Go (Golang) 编写的轻量级 web 框架&#xff0c;运行速度非常快&#xff0c;擅长 Api 接口的高并发&#xff0c;如果项目的规模不大&#xff0c;业务相对简单&#xff0c;这个时候我们也推荐您使用 Gin&#xff0c;特别适合微服务框架。 我自己也是Go开发方面的菜鸟…

基于SpringBoot的“校园台球厅人员与设备管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“校园台球厅人员与设备管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 系统首页界面图…

XUbuntu22.04之激活Linux最新Typora版本(二百二十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Python数据结构实验 图实验(二)

一、实验目的 1&#xff0e;掌握生成树和最小生成树方法&#xff0c;包括普里姆算法设计和克鲁斯卡尔算法设计&#xff1b; 2&#xff0e;掌握求解图的最短路径方法&#xff0c;包括单源最短路径的狄克斯特拉算法设计和多源最短路径的弗洛伊德算法设计&#xff1b; 3&#x…

动态规划——回文串问题

目录 练习1&#xff1a;回文子串 练习2&#xff1a;最长回文子串 练习3&#xff1a;回文串分割IV 练习4&#xff1a;分割回文串 练习5&#xff1a;最长回文子序列 练习6&#xff1a;让字符串成为回文串的最小插入次数 本篇文章主要学习使用动态规划来解决回文串相关问题&…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑新能源发电商租赁共享储能的电力市场博弈分析》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

将使用realsense相机录制的bag转化为TUM数据集格式

GitHub - kinglintianxia/bag2tum: ROS bag to tum dataset style files 基于以上代码进行实现&#xff1a; 1.创建文件夹&#xff1a; image ├── depth └── rgb 2.修改bag2tum.launch文件中的&#xff1a;save_folder, rgb_topic 和depth_topic参数&#xff1a; <par…

LeetCode Python - 83. 删除排序链表中的重复元素

目录 题目描述解法运行结果 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2] 示例 2&#xff1a; 输入&#x…

LeetCode题练习与总结:N皇后

一、题目描述 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决…

Matlab将日尺度数据转化为月尺度数据

日尺度转化为月尺度 clcclear all% load datadata xlread(data.xlsx) % 例如该数据为1961-01-01至2022-12-31&#xff0c;共计22645天data data(:,1:3) % 该数据有22645行&#xff0c;数据分别为降水&#xff0c;气温&#xff0c;湿度等三列dt datetime(1961-01-01):datatim…

政安晨:【Keras机器学习实践要点】(十)—— 自定义保存和序列化

目录 导言 涵盖的API Setup 状态保存自定义 构建和编译保存自定义 结论 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在…

线程的安全问题

目录 导言&#xff1a; 正文&#xff1a; 1.共享资源&#xff1a; 2.非原子操作&#xff1a; 3.执行顺序不确定&#xff1a; 4.可见性&#xff1a; 5.死锁和饥饿&#xff1a; 6.指令重排序&#xff1a; 总结&#xff1a; 导言&#xff1a; 线程安全是并发编程中的一个…

文献阅读:使用 CellChat 推理和分析细胞-细胞通信

文献介绍 「文献题目」 Inference and analysis of cell-cell communication using CellChat 「研究团队」 聂青&#xff08;加利福尼亚大学欧文分校&#xff09; 「发表时间」 2021-02-17 「发表期刊」 Nature Communications 「影响因子」 16.6 「DOI」 10.1038/s41467-0…

Vue3 使用 v-bind 动态绑定 CSS 样式

在 Vue3 中&#xff0c;可以通过 v-bind 动态绑定 CSS 样式。 语法格式&#xff1a; color: v-bind(数据); 基础使用&#xff1a; <template><h3 class"title">我是父组件</h3><button click"state !state">按钮</button>…

解析CUDA FATBIN格式

参考文档&#xff1a; https://pdfs.semanticscholar.org/5096/25785304410039297b741ad2007e7ce0636b.pdf CUDA Pro Tip: Understand Fat Binaries and JIT Caching | NVIDIA Technical Blog cuda二进制文件中到底有什么 - 知乎 NVIDIA CUDA Compiler Driver NVIDIA CUDA…