glidedsky CSS反爬题 详细注释
本帖最后由 jermey1994 于 2019-7-30 20:46 编辑这题数据有垃圾数据,乱序数据,::before数据 在<style>标签中存放 移位和::before数据.
如图 :
# -*-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)) # 获取该名称的数值
num_dict = 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 = filter_num # 把一组数据(列表)给num_dict 方便分析计算
for del_num in css_del_names: # 把每个需要过滤的数据遍历对比删除
if del_num in num_dict: # 如果该列表当中存在无用数据则删除此数据
num_dict.remove(del_num)
if filter_num2: # 是以存在原正确数据的话 直接放进字典
num_dict = 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 # 直接把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
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 :
if len(nums_dict) == 1 : # 如果 这组数据长度为1 就是以存在before 中的真实数据,直接添加
num_lists.append(int(before_dict]))
else :
index = 0
for temp in nums_dict : # 长度大于1 的就是乱序数据
if temp in count_dict : # 遍历每组当中的存在乱序的数据,如果数据没存在乱序列表中则 在该数据(百十个)位当中保持自己的位置不变
move_num)] = data_nums # 把第index个数据 + 上偏移值获得正确位置
else :
move_num = data_nums # 获取原来位置
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()
{:10_270:} 先收藏,有时间再看嘿嘿 看了你的博客 才做出这题的 一直被数字偏移这卡住,感谢!
页:
[1]