最近发现的一个爬虫练习网站,尝试着做了几道题,发现覆盖面很大,因此来记录分享一下自己的解题思路。
http://glidedsky.com/

第一题和第二题

两道问题都是相似的问题,区别在于一个数据加载在一页,一个数据加载在1000页中。
但是要注意的是:直接用requests库请求目标网址会要求登录认证,因此要先把自己的登录信息获取。

进入登录页面,尝试登录,发现浏览器发起了两次请求,一次post请求,然后发生了重定向,又对登录页面发起了一次get请求。可以先看看post请求传递了什么参数

发现post请求传递了三个参数:_token,password,email,后两者都是未加密的直接输入的参数,第一个可以通过搜索发现是一个在网页源代码中随机生成的字符串。


对于_token参数的获取,可以用re正则库匹配。

datas = {"email": "@qq.com",#你的账号"password": "",#你的密码'_token': '',
}
heads={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36"
def login():url = 'http://glidedsky.com/login'session = requests.Session()req = session.get(url).textresult = re.search('input type="hidden" name="_token" value="(.*?)"', req)token = result.group(1)datas['_token'] = tokenreq=session.post(url=url, data=datas,headers=heads)print("post status_code:",req.status_code)return session

利用这个返回值session,就可以携带我们的登录信息,请求访问目标网站而不用进行登录验证了。
对于第一题和第二题的数字计算,因为检查网页源代码发现目标数字能直接搜到,
因此直接通过xpath获取到数字内容并进行求和就可以了。

def crawler_basic_1():#第一题session = login()start_time=time.time()req = session.get('http://glidedsky.com/level/web/crawler-basic-1',headers=heads)tree=etree.HTML(req.text)num_list=tree.xpath('//div[@class="col-md-1"]')global sumfor num in num_list:a="".join(num.xpath('.//text()')).strip()sum+=int(a)end_time=time.time()print('花费%s' % (end_time-start_time))print(sum)
def crawler_basic_2():#第二题,利用多线程加快速度start_time=time.time()session = login()global threadsnum,sum #定义线程数量thread_list=[]q=queue.Queue()#利用队列来实现线程间数据共享for i in range(1,1001):q.put(i)for i in range(threadsnum):t=threading.Thread(target=crawler_basic_2_sums,args=(session,q))#args传参数 target传函数名thread_list.append(t)for t in thread_list:t.start()for t in thread_list:t.join()end_time=time.time()print('花费%ss' % (end_time-start_time))print(sum)
def crawler_basic_2_sums(session,q):while 1:try:i=q.get_nowait()#队列为空时,不等待 直接抛出异常 通过break跳出循环except BaseException:breakurl='http://glidedsky.com/level/web/crawler-basic-2?page={}'.format(i)print(url)req = session.get(url,headers=heads)tree=etree.HTML(req.text)num_list=tree.xpath('//div[@class="col-md-1"]')global sumfor num in num_list:a="".join(num.xpath('.//text()')).strip()sum+=int(a)

第三题:

因为涉及到ip代理池,没有做。

第四题

http://glidedsky.com/level/web/crawler-font-puzzle-1?page=1
第四题利用的是woff文件字体加密,我的另一篇文章大众点评爬虫也涉及到了这方面的操作。
我们可以发现在开发者工具下和网页中的数字不一样,尝试在全局搜索中搜索该字段的字体属性 font-family: glided_sky;


发现一个很可疑的字段,尝试着把base64后面的字段复制下来用解密工具解密,发现乱码。后来参考了别的博主的文章才知道这个解密后就是我们需要的woff文件。解密后用在线浏览网页Iconfont Preview打开

仔细观察第一段数字后可以发现:
网页显示的 384 源码显示的 259
可以利用woff文件做对应:3对应two也就是2 8对应five也就5 4对应nine也就是9
也就是说 网页显示的数字 通过woff文件的对应字典 形成了源码显示的259

#加密字典
dict={"3":"2","8","5","4":"9"......
}

因此 我们就可以利用woff文件生成字典,利用源代码得到的数字解密出真正的数字

#解密字典
dict={"2":"3","5","8","9":"4"......
}

思路如下:
1.通过正则匹配到base64字符串,并解密生成woff文件
2.利用woff文件生成解密字典
3.利用xpath匹配得到源代码显示的数字,在利用解密字典获得网页显示的数字。

nums_dict={#替换英文为数字"one":"1","two":"2","three":"3","four":"4","five":"5","six":"6","seven":"7","eight":"8","nine":"9","zero":'0'}
def crawler_font_puzzle_1_down_woff(req,filename):#解密并保存woff文件gz=re.compile('base64,(.*?)\)')result=gz.search(req).group(1)# print(result)r=base64.b64decode(result)with open('%s.woff'%filename,'wb') as f:f.write(r)# print('woff文件保存完成')
def get_fonts_dict(fontpath):#利用TTfont解析woff文件font = TTFont(fontpath+'.woff')  # 打开文件codeList = font.getGlyphOrder()[1:]#获取英文数字的列表arrayList = codeListdc={}#输出字典word=[str(i) for  i in range(0,10)]for arra,wor in zip(arrayList,word):arra=nums_dict[arra]#把英文单词利用字典转变为字母dc[arra]=worreturn dc
def crawler_font_puzzle_1_sums(session,q,filename):#线程执行的任务函数 进行解密并求和global sumwhile 1:try:i=q.get_nowait()except BaseException:print(BaseException)breakurl='http://glidedsky.com/level/web/crawler-font-puzzle-1?page={}'.format(i)print(url)req=session.get(url=url,headers=heads).textwith open('f.html','w',encoding='utf-8') as f:f.write(req)tree=etree.HTML(req)crawler_font_puzzle_1_down_woff(req,filename)dc=get_fonts_dict(filename)nums_list=tree.xpath('//div[@class="col-md-1"]/text()')for nums in nums_list:true_nums=""nums=nums.strip()for num in nums:true_nums+=dc[num]print(int("".join(true_nums)))sum+=int("".join(true_nums))time.sleep(5)
def   crawler_font_puzzle_1():#主函数q=queue.Queue()for i in range(1,1001):q.put(i)filename='f'session=login()start=time.time()thread_list=[]global sum,threadsnumfor i in range(threadsnum):t=threading.Thread(target=crawler_font_puzzle_1_sums,args=(session,q,filename))thread_list.append(t)for  t in thread_list:t.start()for t in thread_list:t.join()end=time.time()print('花费%ss' % (end-start))print(sum)

输出如下,成功解密

第五题

http://www.glidedsky.com/level/web/crawler-css-puzzle-1?page=1
本题采用了css加密,需要仔细观察,找到规律后才能实现解密并获取数据。
同样发现网页显示内容与源码内容不同,发现各个class名不同,copy进去搜索一下


搜索后发现在源码中有各个class名对应的属性值,但是有着一个class有多条属性值的情况,因此先用正则匹配,并处理成一个字典方便观察。

def get_css_dict():url='http://www.glidedsky.com/level/web/crawler-css-puzzle-1?page=1'session=login()req=session.get(url=url,headers=heads).textgz=re.compile('\.([A-Za-z0-9]*).*?{(.*?)}')css_list=re.findall(gz,req)css_dict={}#把提取到的属性合并为字典for i in css_list:a="".join(i[1]).strip()a=a.split(':')#分割属性名与属性值if i[0]  not in css_dict.keys():dic={}#未保存过该class名的属性 新建字典else:dic=css_dict[i[0]]#保存过该class名的属性 获取字典dic[a[0]]=a[1]css_dict[i[0]]=(dic)css_list.clear()return css_dict

最终生成这样的字典,结合网页观察初步发现有以下的属性比较重要:
[‘opacity’]:存在该属性,对应数字不是我们需要的真实数字
[‘content’]:存在该属性,其内容就是我们需要的真实数字,且在源代码中显示为::before
[‘left’]:存在该属性,对应数字是我们需要的真实数字,但是其在源代码中的位置与网页的位置不同。

对于前面两个属性,我们可以在遇到的时候跳过或者直接取值,对于left属性,推测数字内容为其偏移位置。

对left属性的进一步分析如下:



可以发现:当不存在[‘opacity’]属性的class元素时,数字真实位置=源代码位置+left值。
当存在[‘opacity’]属性的class元素时,数字真实位置=源代码位置+left值-[‘opacity’]出现次数

思路如下:
1.通过正则获取到class元素的属性,并整理成字典
2.通过xpath获取源代码的class名,利用字典中各个属性的存在与否以及属性值实现解密

def crawler_css_puzzle_1():session=login()start=time.time()global threadsnum,sumthreads_list=[]q=queue.Queue()for i in range(1,1001):q.put(i)for i in range(threadsnum):t=threading.Thread(target=crawler_css_puzzle_1_sums,args=(session,q))threads_list.append(t)for t in threads_list:t.start()for t in threads_list:t.join()end=time.time()print('花费%ss' % (end-start))print(sum)
def crawler_css_puzzle_1_sums(session,q):while 1:try:i=q.get_nowait()except BaseException:print(BaseException)breakurl='http://www.glidedsky.com/level/web/crawler-css-puzzle-1?page={}'.format(i)print(url)req=session.get(url=url,headers=heads).textsave_html(req)gz=re.compile('\.([A-Za-z0-9]*).*?{(.*?)}')css_list=re.findall(gz,req)css_ditc={}#把提取到的属性合并为字典for i in css_list:a="".join(i[1]).strip()a=a.split(':')if i[0]  not in css_ditc.keys():dic={}else:dic=css_ditc[i[0]]dic[a[0]]=a[1]css_ditc[i[0]]=(dic)css_list.clear()tree=etree.HTML(req)num_list=tree.xpath('//div[@class="col-md-1"]')global sum#全局变量sum 计算总和for num in num_list:class_l=num.xpath('.//div/@class')nums_l=num.xpath('.//div/text()')class_l=list(class_l)nums_l=list(nums_l)numss=['','','']#这个列表用来存放最终得到的三位数if len(nums_l)<3: #列表小于3 说明有before 直接拿for c in class_l:if 'content' in css_ditc[c].keys():gz=re.compile(r'\d{3}')#匹配三位数numss[0]=re.findall(gz,css_ditc[c]['content'])[0]else:xz=0#修正偏移量for c,n in zip(class_l,range(len(nums_l))):key_list=css_ditc[c].keys()i=css_ditc[c]if 'opacity' in   key_list:xz+=1#跳过了一个数字 偏移量加一continueelif 'left' in   key_list:string=css_ditc[c]['left']gz=re.compile('[\-0-9]{1,2}')number=gz.search(string)number=int(number.group(0))#获得实际位置sj_wz=n+number-xznumss[sj_wz]=str(nums_l[n])else:#没有left和opacity 根据循环次数-偏移量直接给列表赋值numss[n-xz]=str(nums_l[n])numss=int("".join(numss))  # print(numss)sum+=numss

输出如下

glided_sky 镀金的天空 爬虫闯关1-2 4-5 解题思路加代码相关推荐

  1. glided_sky 镀金的天空 爬虫闯关 js加密1

    最近发现的一个爬虫练习网站,尝试着做了几道题,发现覆盖面很大,因此来记录分享一下自己的解题思路. http://glidedsky.com/ JS加密 目标网址 打开开发者工具观察网络请求相应,发现该 ...

  2. 黑板课爬虫闯关第一关

    之前也没有系统的学习过python,看其他源码的时候也是似懂非懂的看着理解意思.最近比较有空,就想更系统的学习一下,在知乎上看到大神推荐了一个Python爬虫闯关网站,便想试试. 下面是第一关的介绍, ...

  3. Python 爬虫闯关

    (个人经验,仅供参考,错误之处,敬请谅解) 前言 学到python的爬虫,有个链接是黑板课闯爬虫关的,于是去试了下     第一关     第二关     第三关:链接以此类推,不过有个防护,登陆之后 ...

  4. Python爬虫入门教程 87-100 glidedsky网站爬虫解析,爬虫闯关第一篇

    写在前面 最近查阅github的时候,发现一个网站http://glidedsky.com/,竟然是一个爬虫练习的网站,作为一个爬虫爱好者,还是有必要挑战一下的,而且看了一下网站的定位,感觉非常棒. ...

  5. python闯关游戏_Python爬虫闯关游戏(第三关)

    打开网址,发现需要先注册: 注册一下登陆: 发现和第二关一样,这一关是加了一个登陆,下面开始闯关: import requests from bs4 import BeautifulSoup def ...

  6. 一个爬虫练习游戏:黑板课爬虫闯关

    网址:http://www.heibanke.com/lesson/crawler_ex00/ 大概用了一小天的时间吧,把这五关给过了,还挺好玩的.推荐小白玩玩.直接po代码了. 我装pytesset ...

  7. Android:关灯游戏简单闯关

    Demo地址:http://download.csdn.net/detail/yyn_12138/9673802 今天来实现一下5*5的关灯游戏, 其中内置一个不可以点击的石头来增加一下闯关难度 先来 ...

  8. python闯关训练营怎么样3.0_泡着枸杞写bug的三流程序员凭什么逆袭到一线大厂?...

    大多数互联网的从业者都有一个梦想:进大厂. 因为不仅可以享受较好的福利待遇,也能与更优秀的人一起共事,获得更专业.更快速的成长. 最近经常有朋友提及想要入门编程学习,该如何学习? 关于编程学习,各种语 ...

  9. 来闯关吗?一个有趣的 Python 解谜网站!我已经懵逼了!

    这一期的话题是:一个学习 Python 的趣味网站 . 最近在网上看到一个非常有意思的 Python 游戏通关网站,一共有 33 关,每一关都需要利用 Python 知识解题找到答案,然后进入下一关. ...

最新文章

  1. NodeJS起步两三事
  2. png 转数组 工具_推荐8款实用在线制图工具
  3. 复习javascript中call,apply,bind的用法
  4. 台积电放大招:甩开英特尔 7nm和5nm芯片将诞生
  5. 逻辑代数01律的理解_零基础学习计算机原理:布尔逻辑和逻辑门
  6. (python)数据结构------列表
  7. Linux 命令(52)—— ipcrm 命令
  8. 非基元类型数据结构_Java数据类型–基元和二进制文字
  9. MIKE21学习总结(一)
  10. 计算机视觉及OpenCV入门简介
  11. 计算机快捷键英语,输入法电脑中英文切换快捷键
  12. 黑名单将公开 我国建立行贿犯罪档案查询系统
  13. android仿微信发状态图片上传
  14. 【Zookeeper】分布式集群(详细图文)
  15. react中 ajax跨域请求
  16. wechat4j开发-菜单创建
  17. 基于rt-thread的udp客户端
  18. Problem F. Asperger Syndrome
  19. uboot代码详细分析.pdf
  20. Netty聊天程序(2):从0开始实战100w级流量应用 - 图解Netty系列

热门文章

  1. php控制电脑关机,window_Windows7系统语音识别功能控制电脑操作,记得若干年前非常真实的一幕 - phpStudy...
  2. 【JAVA上传图片到服务器实现远程访问---3种方法】
  3. 快速搭建基于beanstalk的php消息队列服务
  4. 【Redis】部署架构 - 单节点
  5. Crypto世界的显学:先驱熵学
  6. html网页制作期末大作业成品:基于HTML+CSS+JavaScript简洁汽车网站(7页)
  7. Charles 4.2.5 Mac and Win通用破解文件
  8. VUE(10)--添加背景图片以及背景图片自适应
  9. 长期使用计算机的危害,长期使用电脑危害大 3个方法可降低
  10. 8半导体二极管的伏安特性和电流方程