【数字反爬练习】:解决Steamoat反爬虫(附源代码)

目录

一、需求 

二、思路和步骤

1、网页检查分析

 2、检索css和svg文件

检索css文件 

编写获取css文件关键信息的代码

 检索svg文件

 编写获取svg文件关键信息的代码

3、破解方式

单独破解“口味评分”演示

 演示的完整代码

运行结果 

三、源代码

运行结果


  • 以下提供反爬虫练习的网址:

http://www.porters.vip/confusion/food.htmlhttp://www.porters.vip/confusion/food.html

一、需求 

我们需要获取到的是:口味、服务的评分以及电话

 但是,在网页检查中,评分和电话的数据都被隐藏了起来,这就是数字反爬。我们需要绕过数字反爬,获取到我们想要的数据。



二、思路和步骤

1、网页检查分析

首先进行网页检查,查看被隐藏数据,发现这些被隐藏的数据的位置只有属性值,这些属性值就是我们“破案”的关键线索。

 

 2、检索css和svg文件

  • 检索css文件 

  • 我们先用点击被隐藏数据的位置的那一行

  • 这时右边的样式栏中出现了css文件,点击进入此css文件

  •  food.css文件中会出现该属性值所在的网页的位置,而这些位置信息,就是我们需要获取的信息

  • 编写获取css文件关键信息的代码

我们先基本写出一个能获取css文件关键信息的代码,等到后面整合代码的时候再完善。 

  •  进入网络抓包,找到这个food.css

  • 编写代码
import re
import requests


css_url = 'http://www.porters.vip/confusion/css/food.css'
headers = {
    "User-Agent": '' # User-Agent用自己的哦!
}

css_content = requests.get(css_url, headers=headers).text
# 属性值
class_content = 'vhkjj4'
# 获取属性的坐标值
x, y = re.findall(r'.%s {\n..background: -(.*?)px -(.*?)px;\n}' % class_content, css_content)[0]
print(x)
print(y)
  •  运行结果

  •  检索svg文件

我们在找svg文件时可能不知道应该应该找哪个svg文件,但是我们需要记住的是,大多的数据都是有关联的,找到可能的那个它。

  •  我们在检索文件包时发现一个可能的包,food.svg,为什么可能?因为它和food.css只有后缀不同。
  • 点击food.svg文件,然后点击“预览”,这时我们可以看到有一堆数字,而我们想要的信息就在这堆数据里面,我们需要去破解(下面会说破解方式)

  •  点击“响应”(response),我们会看到四行x数据,向右边滑动,看到右边有四行y的数据,这些y的文本值就是我们在“预览”中的数据,我们需要获取它们,还需要获取的是y的属性值

  • 我们还需要在里面获取字体大小的值(具体用法后面会说)

  •  编写获取svg文件关键信息的代码

先基本写出能获取y的文本值、y的属性值、字体大小数据的代码 

import re
import requests
svg_url = 'http://www.porters.vip/confusion/font/food.svg'
headers = {
    'User-Agent': ''# User-Agent用自己的哦
}

svg_content = requests.get(svg_url,headers=headers).text
# 获取svg页面源码中y的文本值
a, b, c, d = re.findall('y=.*?>(.*?)<', svg_content)
# 获取svg页面源码中y的属性值
y_1, y_2, y_3, y_4 = re.findall('y="(.*?)">', svg_content)
# 获取字体大小
divisor = eval(re.search('x="(\d{2}) ', svg_content).group(1))

print(a)
print(y_1)
print(divisor)
  • 运行结果

3、破解方式

通过“检索css和svg文件”这一步后,我们知道了应该获取的信息有:

  • 属性值的坐标:x、y
  • 字体大小
  • y的属性值
  • y的文本值
  • 单独破解“口味评分”演示

  • 通过网页,手动拿下一些数据,“口味评分”属性值的坐标x、y和其他数据
# 属性值的x、y
x = 316
y = 141

# 字体大小
divisor = 14

# y的属性值
y_1, y_2 ,y_3 ,y_4 = 38,83,120,164

# y的文本值
a = '154669136497975167479825383996313925720573'
b = '560862462805204755437571121437458524985017'
c = '671260781104096663000892328440489239185923'
d = '684431081139502796807382'
  • 首先我们用x值(316)取整除于字体大小(14):x//divisor (316//14)
  • 然后判断y值(141)是否小于y的某个属性值,在这个例子中:y<y_4
  • 接着选择y_4的属性值对应的文本:d
  • x//divisor的结果是一个索引值,即:d[x//divisor] 的结果就是我们想要的数据
completed_nums = ''
if y < y_1:
    completed_nums += a[x // divisor]
elif y < y_2:
    completed_nums += b[x // divisor]
elif y < y_3:
    completed_nums += c[x // divisor]
elif y < y_4:
    completed_nums += d[x // divisor]
  •  演示的完整代码

# 属性值的x、y
x = 316
y = 141

# 字体大小
divisor = 14

# y的属性值
y_1, y_2 ,y_3 ,y_4 = 38,83,120,164

# y的文本值
a = '154669136497975167479825383996313925720573'
b = '560862462805204755437571121437458524985017'
c = '671260781104096663000892328440489239185923'
d = '684431081139502796807382'

completed_nums = ''
if y < y_1:
    completed_nums += a[x // divisor]
elif y < y_2:
    completed_nums += b[x // divisor]
elif y < y_3:
    completed_nums += c[x // divisor]
elif y < y_4:
    completed_nums += d[x // divisor]
print(completed_nums)
  • 运行结果 

 



三、源代码

 我们将想破解的数据的属性值放在一个列表里,然后通过循环遍历,获取数据.

import requests
import re
from lxml import etree
class Shuzi(object):
    def __init__(self):
        # css文件链接
        self.css_url = 'http://www.porters.vip/confusion/css/food.css'
        # 包含数字的svg文件链接
        self.svg_url = 'http://www.porters.vip/confusion/font/food.svg'

        # 属性值列表
        self.class_list = ['vhkjj4','vhkqsc','vhkbvu','vhk08k','vhk08k','vhk84t','vhk6zl','vhkqsc','vhkqsc','vhk6zl']
        # 构建请求头
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36',
        }

    # 获取css定位信息
    def get_coordinate_value(self,order_class):
        css_html = requests.get(self.css_url, headers=self.headers).text
        # 获取属性的坐标值
        info_css = re.findall(r'.%s {\n..background: -(.*?)px -(.*?)px;\n}' %order_class, css_html)[0]
        return info_css

    def get_completed_nums(self):
        self.completed_nums = ''
        svg_html = requests.get(self.svg_url, headers=self.headers).text
        # 获取svg页面源码中y的文本值
        a,b,c,d = re.findall('y=.*?>(.*?)<',svg_html)
        # 获取text标签内y的属性值
        y_1,y_2,y_3,y_4= re.findall('y="(.*?)">', svg_html)
        # 获取字体大小
        divisor = eval(re.search('x="(\d{2}) ', svg_html).group(1))

        for i in self.class_list:
                x, y = self.get_coordinate_value(i)
                x, y = int(x), int(y)
                if y < int(y_1):
                    self.completed_nums += a[x // divisor]
                elif y < int(y_2):
                    self.completed_nums += b[x // divisor]
                elif y < int(y_3):
                    self.completed_nums += c[x // divisor]
                elif y < int(y_4):
                    self.completed_nums += d[x // divisor]

    def run(self):
        self.get_completed_nums()
        print(f'口味:{self.completed_nums[0] + ".7"}')
        print(f'服务:{self.completed_nums[1] + ".6"}')
        print(f'电话:{self.completed_nums[2:]}')

s = Shuzi()
s.run()

运行结果

 

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

街 三 仔

你的鼓励是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值