鱼C论坛

 找回密码
 立即注册
查看: 2785|回复: 3

[技术交流] glidedsky CSS反爬题 详细注释

[复制链接]
发表于 2019-7-30 15:23:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 jermey1994 于 2019-7-30 20:46 编辑

TIM截图20190730151800.png

这题数据有垃圾数据,乱序数据,::before数据 在<style>标签中存放 移位和::before数据.
如图 :
TIM截图20190730204304.png
# -*-coding:utf-8 -*-
# Author : Jermey1994
# Develop_Time : 2019/7/28 11:44
# File_Name : css_sky.PY
# Develop_Tool : PyCharm

import requests
import re
from bs4 import BeautifulSoup
from fake_useragent import UserAgent

class CSS_SkyMain(object):
    def __init__(self,page=1):
        """
        初始化一个存放每页数值的总和变量和header参数
        :param page: 页数
        """
        self.sum_nums = 0
        self.page = page
        self.header = {'User-Agent':UserAgent().random,
          'Cookie': '******',
          }

    def get_html_soup(self,url):
        """
        返回BeautifulSoup对象方便获取数据
        :param url:
        :return:
        """
        response = requests.get(url,headers=self.header).text
        soup = BeautifulSoup(response,'lxml')
        return soup

    def get_nums_datadict(self,soup):
        """
        筛选出源码当中需要的名称对应的值,放在一个字典当中
        :param soup:
        :return: 字典
        """
        num_dict = dict()
        num_countent = soup.select(".col-md-1")
        css_label = soup.find_all('style')

        css_content_label = re.findall(r'\.(.*?):before \{ content:"(.*?)" \}', str(css_label)) # 筛选出 before : 当中已存在的值
        css_del_names = re.findall(r'\.(.*?) { margin-right:-1em }', str(css_label)) # 筛选出 不显示化的数值
        for temp in num_countent: # 遍历每组 class=col-md-1 的数据
            num_names = re.findall(r'class="(.*?)">\d<', str(temp)) # 筛选出 带有 数值的名称及值 返回一个list
            for name in num_names: # 遍历 筛选出来的数据
                if name not in css_content_label and name not in css_del_names: # 判断该数据 是否不在 已带有正确数据 和 不显示化数据 的列表当中, 不在才添加进字典中保存
                    nums = re.findall(r'class="%s">(\d)</div>' % name, str(temp))[0] # 获取该名称的数值
                    num_dict[name] = nums # key: 名称,value : 名称对应的值

        return num_dict


    def get_nums_dict(self,soup):
        """
        获取正确数据的名称
        :return: 字典
        """
        index = 1
        num_dict = dict()
        num_countent = soup.select(".col-md-1")
        css_label = soup.find_all('style')
        css_del_names = re.findall(r'\.(.*?) { margin-right:-1em }', str(css_label)) # 设置筛选无用名称的列表
        for num in num_countent:
            filter_num = re.findall(r'class="(.*?)">\d<', str(num)) # filter_num 为带有K,V值的名称
            filter_num2 = re.findall(r'class="(.*?)"><', str(num)) # filter_num2 为以在before 存在数据的
            if filter_num: # 不为空列表
                num_dict[index] = filter_num # 把一组数据(列表)给num_dict[index] 方便分析计算
                for del_num in css_del_names: # 把每个需要过滤的数据遍历对比删除
                    if del_num in num_dict[index]: # 如果该列表当中存在无用数据则删除此数据
                        num_dict[index].remove(del_num)
            if filter_num2: # 是以存在原正确数据的话 直接放进字典
                num_dict[index] = filter_num2
            index += 1
        return num_dict

    def get_before_dict(self,soup):
        """
        获取以存在html中的正确数据
        :return:
        """
        before_dict = dict()
        css_label = soup.find_all('style')
        css_content_label = re.findall(r'\.(.*?):before \{ content:"(.*?)" \}', str(css_label))
        for cont in css_content_label:
            before_dict[cont[0]] = cont[1] # 直接把before的名称及数值 加进字典
        return before_dict

    def get_count_dict(self,soup):
        """
        获取 left 的移位值(因为这些数值位置都是打乱的,通过left参数获取移动位置)如 -1 就是该值 当前位数的 左移动移位
        :return: 返回带有left值的名称和left值
        """
        count_dict = dict()
        css_label = soup.find_all('style')
        css_left_label = re.findall(r'\.(.*?) \{ left:(.*?)em \}', str(css_label))
        for count in css_left_label:
            count_dict[count[0]] = count[1]
        return count_dict

    def start_main(self):
        """
        入口函数
        :return:
        """
        for page in range(1,self.page + 1) :
            url = 'http://glidedsky.com/level/web/crawler-css-puzzle-1?page=' + str(page) # 初始化url
            soup = self.get_html_soup(url)

            # 获取未移动的乱位数值 如{'FyS3OKrlU': '2', 'oDi4pqFmA': '1', 'GO5QRpPL': '8', 'Uyr7Txf': '4', 'EOkXH8HikS': '9', 'xgOI9HCVew': '0',
            # 'Vgqo13pntW': '1', 'izqGi14tTL': '3', 'wY15IOHs': '4', 'SxdvY17HFB': '0', 'pDn18BCP': '4', 'dc19cxCL': '1', 'nHTT28FNo': '6', 'lK29nnV': '9', 'OQ30QrUL': '2'}
            data_nums = self.get_nums_datadict(soup)

            # 获取每组数据 如{1: ['dnQt1XiIt'], 2: ['FyS3OKrlU', 'oDi4pqFmA', 'GO5QRpPL'], 3: ['Uyr7Txf', 'EOkXH8HikS', 'xgOI9HCVew'], 4: ['auA11eUJgz'],
            # 5: ['Vgqo13pntW', 'izqGi14tTL', 'wY15IOHs'], 6: ['SxdvY17HFB', 'pDn18BCP', 'dc19cxCL'], 7: ['ww20pqR'], 8: ['YWm22LTd'], 9: ['LPg24MhlF'],
            # 10: ['ANG25uFYtJ'], 11: ['DHUy26NUu'], 12: ['nHTT28FNo', 'lK29nnV', 'OQ30QrUL']}
            nums_dict = self.get_nums_dict(soup)

            # 获取已存在的真实数据 如{'LPg24MhlF': '310', 'dnQt1XiIt': '272', 'ANG25uFYtJ': '353', 'ww20pqR': '176', 'DHUy26NUu': '282', 'YWm22LTd': '182', 'auA11eUJgz': '130'}
            before_dict = self.get_before_dict(soup)

            # 获取对应的移位数据 如{'nHTT28FNo': '1', 'SxdvY17HFB': '2', 'lK29nnV': '1', 'OQ30QrUL': '-2', 'dc19cxCL': '-2', 'FyS3OKrlU': '1', 'xgOI9HCVew': '-1', 'EOkXH8HikS': '1', 'oDi4pqFmA': '-1'}
            count_dict = self.get_count_dict(soup)

            num_lists = list() # 生成一个列表用来sum() 运算
            for key,value in nums_dict.items() :
                move_num = ['0','0','0'] # 移位使用
                if nums_dict[key] :
                    if len(nums_dict[key]) == 1 : # 如果 这组数据长度为1 就是以存在before 中的真实数据,直接添加
                        num_lists.append(int(before_dict[nums_dict[key][0]]))
                    else :
                        index = 0
                        for temp in nums_dict[key] : # 长度大于1 的就是乱序数据
                            if temp in count_dict : # 遍历每组当中的存在乱序的数据,如果数据没存在乱序列表中则 在该数据(百十个)位当中保持自己的位置不变
                                move_num[index + int(count_dict[temp])] = data_nums[temp] # 把第index个数据 + 上偏移值获得正确位置
                            else :
                                move_num[index] = data_nums[temp] # 获取原来位置

                            index += 1
                        str_temp = ''
                        for all_num in move_num :
                            str_temp += all_num
                        num_lists.append(int(str_temp))

            self.sum_nums += sum(num_lists) # 把列表总和加入到总数当中计算
            print('No.%d'%page)
            print(num_lists)
            print(self.sum_nums)


start = CSS_SkyMain(1000)
start.start_main()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-7-30 21:06:47 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-19 22:36:54 | 显示全部楼层
先收藏,有时间再看嘿嘿
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-23 12:41:24 | 显示全部楼层
看了你的博客 才做出这题的 一直被数字偏移这卡住,感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-19 20:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表