鱼C论坛

 找回密码
 立即注册
查看: 2997|回复: 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

  1. # -*-coding:utf-8 -*-
  2. # Author : Jermey1994
  3. # Develop_Time : 2019/7/28 11:44
  4. # File_Name : css_sky.PY
  5. # Develop_Tool : PyCharm

  6. import requests
  7. import re
  8. from bs4 import BeautifulSoup
  9. from fake_useragent import UserAgent

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

  21.     def get_html_soup(self,url):
  22.         """
  23.         返回BeautifulSoup对象方便获取数据
  24.         :param url:
  25.         :return:
  26.         """
  27.         response = requests.get(url,headers=self.header).text
  28.         soup = BeautifulSoup(response,'lxml')
  29.         return soup

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

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

  47.         return num_dict


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

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

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

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

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

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

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

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

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

  124.                             index += 1
  125.                         str_temp = ''
  126.                         for all_num in move_num :
  127.                             str_temp += all_num
  128.                         num_lists.append(int(str_temp))

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


  133. start = CSS_SkyMain(1000)
  134. start.start_main()

复制代码

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-7-30 21:06:47 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-19 22:36:54 | 显示全部楼层
先收藏,有时间再看嘿嘿
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-23 12:41:24 | 显示全部楼层
看了你的博客 才做出这题的 一直被数字偏移这卡住,感谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-24 04:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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