字体反爬案例分析与爬取实战

字体反爬案例分析与爬取实战

该案例将真实的数据隐藏到字体文件里,即使获取了页面源代码,也没法直接提取数据的真实值。

  1. 案例介绍

案例网站https://antispider4.scrape.center/,爬取电影标题、类别、评分等,代码实现如下:

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 Serviceoptions = webdriver.ChromeOptions()
services = Service('../Selenium/chromedriver')browser = webdriver.Chrome(service=services, options=options)browser.get('<https://antispider4.scrape.center/>')
WebDriverWait(browser, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.item')))html = browser.page_source
doc = pq(html)
items = doc('.item')
for item in items.items():name = item('.name').text()categories = [o.text() for o in item('.categories button').items()]score = item('.score').text()print(f'name:{name} categories: {categories} score: {score}')
browser.close()

先用Selenium打开案例网站,等待所有电影加载出来,然后获取页面源代码,并通过pyquery提取和解析每一个电影的信息,得到名称、类别和评分,之后输出,运行结果如下:

name:霸王别姬 - Farewell My Concubine categories: ['剧情', '爱情'] score: 
name:这个杀手不太冷 - Léon categories: ['剧情', '动作', '犯罪'] score: 
name:肖申克的救赎 - The Shawshank Redemption categories: ['剧情', '犯罪'] score: 
name:泰坦尼克号 - Titanic categories: ['剧情', '爱情', '灾难'] score: 
name:罗马假日 - Roman Holiday categories: ['剧情', '喜剧', '爱情'] score: 
name:唐伯虎点秋香 - Flirting Scholar categories: ['喜剧', '爱情', '古装'] score: 
name:乱世佳人 - Gone with the Wind categories: ['剧情', '爱情', '历史', '战争'] score: 
name:喜剧之王 - The King of Comedy categories: ['剧情', '喜剧', '爱情'] score: 
name:楚门的世界 - The Truman Show categories: ['剧情', '科幻'] score: 
name:狮子王 - The Lion King categories: ['动画', '歌舞', '冒险'] score: 

很奇怪,结果中的score字段不包含任何信息,怎么回事?观察分析,对应的源代码并不包含数字信息,如图所示:

1

span节点就是什么信息都没有,提取不出来自然也不足为奇了,那页面上的评分结果是怎么显示出来的呢?

其实也是CSS的原因。

  1. 案例分析

观察源码,各个span节点的不同之处在于内部i节点的class取值不太一样。可以看到一共有3个span节点,对应的class取值分别为icon-789、icon-981、icon-504,这和评分9.5有啥关系呢?

2

发现i节点内部有一个::before字段,在CSS中,该字段用于创建一个伪节点,即这个节点和i节点或者span节点不一样。::before可以往特定的节点中插入内容,同时在CSS中使用content字段定义这个内容。第一个i节点看到了9,另外两个i节点,看到.和5,组合起来为9.5。

  1. 实战

那class取值和content字段值的映射关系是怎么定义的?可以在浏览器中追踪CSS源代码,代码如下图所示:

3

进入文件后,可以看到这个CSS源代码都在一行放着,点击“{}”按钮格式化代码,如图所示:

4

可以从中找出如下内容:

.icon-437:before {content: "3"
}.icon-378:before {content: "4"
}.icon-504:before {content: "5"
}.icon-203:before {content: "6"
}.icon-102:before {content: "7"

原来class对应的值就是一个个评分结果。这样我们只要解析对应的结果再做转换即可。这里需要读取CSS文件并提取映射关系,这个CSS文件是https://antispider4.scrape.center/css/app.654ba59e.css,其部分内容如图所示:

5

我们可以试着用requests库读取结果,并通过正则表达式将映射关系提取出来,代码如下:

import re
import requests
url = '<https://antispider4.scrape.center/css/app.654ba59e.css>'response = requests.get(url)
pattern = re.compile('.icon-(.*?):before\\{content:"(.*?)"\\}')
results = re.findall(pattern, response.text)
icon_map = {item[0]: item[1] for item in results}

这里首先使用requests库提取了CSS文件的内容,然后使用正则表达式进行文本匹配,表达式写作.icon-(.?):before{content:”(.?)”},这个表达式并没有考虑空格,因为CSS源代码本身就是一行放着而去去除了所有空格。

例如,对于如下CSS样式:

.icon-789:before{content:"9"}

就会提取得到两个group,第一个是789,第二个是9。

这里使用re里的findall方法进行内容匹配,得到结果如下:

[....., ('asterisk', '*'), ('plus', '+'), ('comma', ','), ('hyphen', '-'), ('981', '.'), ('slash', '/'), ('272', '0'), ('643', '1'), ('180', '2'), ('437', '3'), ('378', '4'), ('504', '5'), ('203', '6'), ('102', '7'), ('281', '8'), ('789', '9'), ('colon', ':'), ('semicolon', ';'), ('less', '<'), ('equal', '='), ('greater', '>'), ('question', '?'), ('at', '@'), ('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D'), ('E', 'E'), ('F', 'F'), ('G', 'G'), ('H', 'H'), ('I', 'I'), ('J', 'J'), ('K', 'K'), ('L', 'L'), ('M', 'M'), ('N', 'N'), ('O', 'O'), ('P', 'P'), ('Q', 'Q'), ('R', 'R'), ('S', 'S'), ('T', 'T'), ('U', 'U'), ('V', 'V'), ('W', 'W'), ('X', 'X'), ('Y', 'Y'), ('Z', 'Z'), ('bracketleft', '['), ('backslash', '\\\\\\\\'), ('bracketright', ']'), ('asciicircum', '^'), ('underscore', '_'), ('grave', '`'), ('a', 'a'), ('b', 'b'), ('c', 'c'), ('d', 'd'), ('e', 'e'), ('f', 'f'), ('g', 'g'), ('h', 'h'), ('i', 'i'), ('j', 'j'), ('k', 'k'), ('l', 'l'), ('m', 'm'), ('n', 'n'), ('o', 'o'), ('p', 'p'), ('q', 'q'), ('r', 'r'), ('s', 's'), ('t', 't'), ('u', 'u'), ('v', 'v'), ('w', 'w'), ('x', 'x'), ('y', 'y'), ('z', 'z'), ('braceleft', '{'), ('bar', '|'), ('braceright', '}'), ('asciitilde', '~'), ('Adieresis', '\\\\80,\\\\C4'), ('Aring', '\\\\81,\\\\C5'), ('Ccedilla', '\\\\82,\\\\C7'), ('Eacute', '\\\\83,\\\\C9'), ('Ntilde', '\\\\84,\\\\D1'), ('Odieresis', '\\\\85,\\\\D6'), ('Udieresis', '\\\\86,\\\\DC'), ('aacute', '\\\\87,\\\\E1'), ('agrave', '\\\\88,\\\\E0'), ('acircumflex', '\\\\89,\\\\E2'), ('adieresis', '\\\\8A,\\\\E4'), ('atilde', '\\\\8B,\\\\E3'), ('aring', '\\\\8C,\\\\E5'), ('ccedilla', '\\\\8D,\\\\E7'), ('eacute', '\\\\8E,\\\\E9'), ('egrave', '\\\\8F,\\\\E8'), ('ecircumflex', '\\\\90,\\\\EA'), ('edieresis', '\\\\91,\\\\EB'), ('iacute', '\\\\92,\\\\ED'), ('igrave', '\\\\93,\\\\EC'), ('icircumflex', '\\\\94,\\\\EE'), ('idieresis', '\\\\95,\\\\EF'), ('ntilde', '\\\\96,\\\\F1'), ('oacute', '\\\\97,\\\\F3'), ('ograve', '\\\\98,\\\\F2'), ('ocircumflex', '\\\\99,\\\\F4'), ('odieresis', '\\\\9A,\\\\F6'), ('otilde', '\\\\9B,\\\\F5'), ('uacute', '\\\\9C,\\\\FA'), ('ugrave', '\\\\9D,\\\\F9'), ('ucircumflex', '\\\\9E,\\\\FB'), ('udieresis', '\\\\9F,\\\\FC'), ('dagger', '\\\\2020'), ('degree', '\\\\B0'), ('cent', '\\\\A2'), ('sterling', '\\\\A3'), ('section', '\\\\A7'), ('bullet', '\\\\2022'), ('paragraph', '\\\\B6'), ('germandbls', '\\\\DF'), ('registered', '\\\\AE'), ('copyright', '\\\\A9'), ('trademark', '\\\\2122'), ('acute', '\\\\B4'), ('dieresis', '\\\\A8'), ('notequal', '\\\\AD,\\\\2260'), ('AE', '\\\\C6'), ('Oslash', '\\\\D8'), ('infinity', '\\\\221E'), ('plusminus', '\\\\B1'), ('lessequal', '\\\\2264'), ('greaterequal', '\\\\2265'), ('yen', '\\\\A5'), ('mu', '\\\\B5'), ('partialdiff', '\\\\2202'), ('summation', '\\\\2211'), ('product', '\\\\220F'), ('pi', '\\\\3C0'), ('integral', '\\\\222B'), ('ordfeminine', '\\\\AA'), ('ordmasculine', '\\\\BA'), ('Omega', '\\\\2126'), ('ae', '\\\\E6'), ('oslash', '\\\\F8'), ('questiondown', '\\\\BF'), ('exclamdown', '\\\\A1'), ('logicalnot', '\\\\AC'), ('radical', '\\\\221A'), ('florin', '\\\\192'), ('approxequal', '\\\\2248'), ('Delta', '\\\\2206'), ('guillemotleft', '\\\\AB'), ('guillemotright', '\\\\BB'), ('ellipsis', '\\\\2026'), .....]

这个结果由很多二元组组成的列表。我们遍历这个列表,将其赋值成字典即可,最后icon_map就变成了如下这样:

{
...
'at':'@',
'A':'A',
'B':'B',
....
'789':'9',
....
'bar':'|',
...
)

例如使用789索引,得到结果就是9。

运行测试一下:

print(icon_map['789'])
print(icon_map['437'])运行结果:
9
3

和源代码保持一致。

所以,只需要修改一下提取逻辑即可,实现代码如下:

import re
import requests
from selenium.webdriver.support.wait import WebDriverWait
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.chrome.service import Service
from selenium import webdriver
url = '<https://antispider4.scrape.center/css/app.654ba59e.css>'response = requests.get(url)
pattern = re.compile('.icon-(.*?):before\\{content:"(.*?)"\\}')
results = re.findall(pattern, response.text)
icon_map = {item[0]: item[1] for item in results}def parse_score(item):elements = item('.icon')icon_values = []for element in elements.items():class_name = (element.attr('class'))icon_key = re.search('icon-(\\d+)', class_name).group(1)icon_value = icon_map.get(icon_key)icon_values.append(icon_value)return ''.join(icon_values)options = webdriver.ChromeOptions()
services = Service('../Selenium/chromedriver')browser = webdriver.Chrome(service=services, options=options)browser.get('<https://antispider4.scrape.center/>')
WebDriverWait(browser, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.item')))
html = browser.page_source
doc = pq(html)
items = doc('.item')
for item in items.items():name = item('.name').text()categories = [o.text() for o in item('.categories button').items()]score = parse_score(item)print(f'name:{name} categories: {categories} score:{score}')
browser.close()

运行结果如下:

name:霸王别姬 - Farewell My Concubine categories: ['剧情', '爱情'] score:9.5
name:这个杀手不太冷 - Léon categories: ['剧情', '动作', '犯罪'] score:9.5
name:肖申克的救赎 - The Shawshank Redemption categories: ['剧情', '犯罪'] score:9.5
name:泰坦尼克号 - Titanic categories: ['剧情', '爱情', '灾难'] score:9.5
name:罗马假日 - Roman Holiday categories: ['剧情', '喜剧', '爱情'] score:9.5
name:唐伯虎点秋香 - Flirting Scholar categories: ['喜剧', '爱情', '古装'] score:9.5
name:乱世佳人 - Gone with the Wind categories: ['剧情', '爱情', '历史', '战争'] score:9.5
name:喜剧之王 - The King of Comedy categories: ['剧情', '喜剧', '爱情'] score:9.5
name:楚门的世界 - The Truman Show categories: ['剧情', '科幻'] score:9.0
name:狮子王 - The Lion King categories: ['动画', '歌舞', '冒险'] score:9.0

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云docker创建容器镜像及仓库

这里为了尽量简单&#xff0c;直接用腾讯云容器版本服务器 腾讯云有自己的镜像加速地址&#xff0c;速度还可以&#xff0c;单纯拉取容器还是够用的 但是当我push容器出现各种各样问题因为网络原因&#xff0c;国内访问docker官方镜像站非常麻烦&#xff0c;所以使用阿里的镜像…

【C++练级之路】【Lv.17】【STL】set类和map类的模拟实现

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C语言》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、红黑树&#xff08;改造版&#xff09;1.1 结点1.2 迭代器1.2.1 operator1.2.2 operator- - 1.3 本体1.…

Vite为什么比Webpack快得多?

Vite为什么比Webpack快得多&#xff1f; 在前端开发中&#xff0c;构建工具扮演着至关重要的角色&#xff0c;而Vite和Webpack无疑是两个备受关注的工具。然而&#xff0c;众多开发者纷纷赞誉Vite的速度之快&#xff0c;本文将深入探讨Vite相较于Webpack为何更快的原因&#xf…

企业知识库搭建不再是难题,靠这几个软件就可以了

在当今知识为王的时代&#xff0c;具备一套强大且实用的企业知识库&#xff08;Knowledge Base&#xff09;已成为提升工作效率、促进团队合作不可或缺的工具。那么&#xff0c;问题来了&#xff0c;我们该如何搭建一套属于自己的知识库呢&#xff1f;今天&#xff0c;我就给大…

WMware虚拟机配置静态IP

注意&#xff1a;如果是克隆的虚拟机&#xff0c;需要先重新生成mac地址&#xff0c;如下图所示 修改配置文件 &#xff1a;/etc/sysconfig/network-scripts/ifcfg-ens33 注意&#xff1a;1. BOOTPROTO设置为static 2.将下面的IPADDR地址替换为你实际要设置的ip地址 3.NAT模式…

前端学习<二>CSS基础——13-CSS3属性:Flex布局图文详解

前言 CSS3中的 flex 属性&#xff0c;在布局方面做了非常大的改进&#xff0c;使得我们对多个元素之间的布局排列变得十分灵活&#xff0c;适应性非常强。其强大的伸缩性和自适应性&#xff0c;在网页开中可以发挥极大的作用。 flex 初体验 我们先来看看下面这个最简单的布局…

软考数据库

目录 分值分布1. 事务管理1.1 事物的基本概念1.2 数据库的并发控制1.2.1 事务调度概念1.2.2 并发操作带来的问题1.2.3 并发控制技术1.2.4 隔离级别&#xff1a; 1.3 数据库的备份和恢复1.3.1 故障种类1.3.2 备份方法1.3.3 日志文件1.3.4 恢复 SQL语言发权限收权限视图触发器创建…

动态规划——回文串问题

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

ES6 学习(一)-- 基础知识

文章目录 1. 初识 ES62. let 声明变量3. const 声明常量4. 解构赋值 1. 初识 ES6 ECMAScript6.0(以下简称ES6)是JavaScript语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff0c;是使得」JavaScript语言可以用来编写复杂的大型应用程序&#xff0c;成为…

新收获——蓝桥杯单片机第十四届国赛程序设计题

大家要是初学&#xff0c;可以去看西风那里的系统课程&#xff0c;非常全面&#xff0c;有利于形成你自己的代码风格。 笔者发文章只是分享性的&#xff0c;有需要者才拿去用其中的一个小片段。 代码在这&#xff1a; 一、这个是首写自主完成的&#xff0c;bug应该也是没有的…

预处理详解(一) -- 预定义符号与#define定义

目录 一. 预定义符号二. #define1.#define定义常量2.#define定义宏3.带有副作用的宏参数4.宏替换的规则5.宏和函数的对比 一. 预定义符号 %s _ _FILE_ _ //文件 %s _ _ DATE_ _ //日期 %s _ _ TIME_ _ //时间 %d _ _ LINE_ _ //行号 %d _ _ STDC_ _ //如果编译器支持 ANSI C,那…

Vmware下减小Ubuntu系统占用系统盘大小

1、虚拟机设置下占用空间 如图&#xff0c;给虚拟机分配了120GB&#xff0c;已经占用116.9GB&#xff0c;开机会提示空间不足。 2、实际使用空间 ubuntu系统下使用“df -h”命令查看实际使用空间大小50GB左右 造成这个原因是&#xff0c;虚拟机的bug&#xff1a;在虚拟机的ub…

算法学习——LeetCode力扣动态规划篇6

算法学习——LeetCode力扣动态规划篇6 121. 买卖股票的最佳时机 121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 描述 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&…

ADC--数模转换器的使用

目录 前言 ADC接口使用 配置准备 确定引脚编号 光敏电阻--PF7​编辑 ADC3_IN5 开始配置 实验进阶 MQ_3--酒精传感器、水位传感器、火焰传感器 前言 ADC(analog-digital conversion)顾名思义模拟数字转换器,把外界的譬如温度、湿度、酒精含量、水位、特殊光波等等的现实…

通过PandasAI使用自然语言进行数据分析

通过PandasAI使用自然语言进行数据分析 介绍 ​ PandasAI是一个Python库&#xff0c;可以很容易地用自然语言向数据提问。它可以帮助您使用生成人工智能来探索、清理和分析数据。 使用PandasAI 这里使用Anaconda和Jupyter使用PandasAI 进入一个文件目录 创建一个 Notebook …

Python | Leetcode Python题解之第2题两数相加

题目&#xff1a; 题解&#xff1a; # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optiona…

LabVIEW无人机大气数据智能测试系统

LabVIEW无人机大气数据智能测试系统 随着无人机技术的迅速发展&#xff0c;大气数据计算机作为重要的机载设备&#xff0c;在确保飞行安全性方面发挥着重要作用。设计了一套基于LabVIEW的无人机大气数据智能测试系统&#xff0c;通过高效、稳定的性能测试&#xff0c;及时发现…

统计XML文件内标签的种类和其数量及将xml格式转换为yolov5所需的txt格式

1、统计XML文件内标签的种类和其数量 对于自己标注的数据集&#xff0c;需在标注完成后需要对标注好的XML文件校验&#xff0c;下面是代码&#xff0c;只需将SrcDir换成需要统计的xml的文件夹即可。 import os from tqdm import tqdm import xml.dom.minidomdef ReadXml(File…

Jenkins执行策略(图文讲解)

Jenkins执行策略-图文讲解 一&#xff1a;手动执行1、手动执行流程2、手动执行操作 二、通过构建触发器——定时执行1、定时执行流程2、定时执行操作 三、当开发部署成功之后进行执行——在测试项配置——关注的项目1、执行流程2、操作流程 四、测试代码有更新的时候自动构建1、…

Kubeflow文档1:介绍与架构

Kubeflow 2024/3/19版本的文档 此专栏用来展示相关的内容翻译&#xff0c;重点关注本地部署&#xff0c;关于运营商的方案&#xff0c;请自行查阅 文档地址https://www.kubeflow.org/docs/ 开始编辑时间&#xff1a;2024/3/27&#xff1b;最后编辑时间2024/3/27 Kubeflow文…