glidedsky网站爬虫解析,爬虫闯关第一篇

879 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情

写在前面

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

以下内容来源 glidedsky.com 网站 About

定位 镀金的天空是一个互联网技能认证网站,要保证用户解出一道题目就意味着拥有了解决类似问题相应的技能,所以会激励以下行为:

解决题目证明自己拥有题目所考核的相关技能。 协助他人学习掌握题目所考核的相关技能。 对应的,会惩罚以下行为:

不具备题目所考核的相关技能的情况下,包括但不限于抄袭答案,代码等形式通过题目。 协助他人在不具备题目所考核的技能的情况下,通过题目。 在题目的设置上,追求:

实用性,题目考察的技能有具体的使用场景。 体系性,一个领域会出一系列题目,保证该领域有全面的认识。

挑战一下,虽然不知道最终可否把全部内容答完,以纯实验的心态来吧。第一步注册一个账号。

答题走起

1. 爬虫-基础 1

请看题目 Python爬虫入门教程 87-100 glidedsky网站爬虫解析,爬虫闯关第一篇

作为一个答题效率者,部分源码以得到正确答案为主,代码会尽量保持美观,哈哈哈

第一题就比较简单了,通过筛选 Cookie,发现只有glidedsky_session用来判断是否登录状态,那这就比较简单了,直接从开发者工具里面赋值过来即可。当然作者的原意应该是让我们模拟登录一下。

代码如下,最终的结果自行计算

import requests
from lxml import etree
# 访问页面为 http://glidedsky.com/level/web/crawler-basic-1
# 注意到如果没有登录,无法访问

headers = {
    'Host': 'glidedsky.com',
    'Referer': 'http://glidedsky.com/level/crawler-basic-1',
    'User-Agent': 'Mozilla/5.0 填写自己的UA',
    'Cookie':'glidedsky_session=从开发者工具将Cookie的值复制一份'
}
def run(url):
    res = requests.get(url,headers=headers)
    html = etree.HTML(res.text)
    numbers = html.xpath("//div[@class='col-md-1']/text()")
    totle = 0
    for number in numbers:
       totle+=int(number)
    print(totle)
if __name__ == "__main__":
    run('http://glidedsky.com/level/web/crawler-basic-1')

2. 爬虫-基础 2

和第二题同时出现的还有一个关注 VX 的任务,大家关注下,记得在 VX 那里也要发送才可以授权,看一下第二题的内容 Python爬虫入门教程 87-100 glidedsky网站爬虫解析,爬虫闯关第一篇 1000 页,页数不是很多,其实这道题最佳解法是多线程,但是作为一个懒惰的爬虫代码编写者,我直接循环走起~

想要学习多线程的,可以参考我之前写的博客 ,本篇博客前后都是关于多线程的

懒人参考代码,为了快速得到结果,我没有做代码的优化哦~千万不要吐槽,当然执行还是比较耗时的,我执行了 1 分多钟,才运行出正确的结果。

import requests
from lxml import etree

# 访问页面为 http://glidedsky.com/level/web/crawler-basic-1
# 注意到如果没有登录,无法访问


headers = {
    'Host': 'glidedsky.com',
    'Referer': 'http://glidedsky.com/level/crawler-basic-1',
    'User-Agent': 'Mozilla/5.0 填写自己的UA',
    'Cookie':'glidedsky_session=从开发者工具将Cookie的值复制一份'
}

def run(url):
    res = requests.get(url,headers=headers)
    html = etree.HTML(res.text)
    numbers = html.xpath("//div[@class='col-md-1']/text()")
    totle = 0
    for number in numbers:
       totle+=int(number)

    return totle
if __name__ == "__main__":
    COUNT = 0
    for i in range(1,1001):
        url = f'http://glidedsky.com/level/web/crawler-basic-2?page={i}'
        COUNT +=run(url)

    print(COUNT)

写完这道题的答案之后,瞬间出来好多题目...考试恐惧症的我,瞬间不想做了 Python爬虫入门教程 87-100 glidedsky网站爬虫解析,爬虫闯关第一篇

3. 爬虫-IP 屏蔽 1

查看题目,结果 打开待爬取的页面,呦呵,给我直接屏蔽了,越来越有意思了 Python爬虫入门教程 87-100 glidedsky网站爬虫解析,爬虫闯关第一篇 屏蔽效果图 Python爬虫入门教程 87-100 glidedsky网站爬虫解析,爬虫闯关第一篇 这题明显的限制 IP 访问,不过有点意思的是,IP 使用一次就不能再用了,那我们需要系统的调整一下代码了,好,最后这个案例好好的写一下,写完收工。

题目中说是总共 1000 页,那么我们需要 1000 个可用的代理 ip 才可以,这就比较麻烦了,代码没有难度。 一开始,我尝试使用免费的 IP,使用搜索引擎可以找到很多免费的,但是找了半天,最终的结果就是没有好用的,最后尝试的方案是找一些出售代理 ip 的网站,然后进行,最终的方案也是修改了比较多的版本

部分代码如下,我尽量在代码注释中对问题进行整体的描述

import requests
import time
from lxml import etree


def get_one_ip():
    # 这个函数为你自己获取IP的方式,我后来找到的是一些代理平台,使用的是限时免费使用,用来测试一下这个题,时间足够了
	# 最后返回一个ips的列表
    return ips

# 计算函数
def calc(text, page):
    html = etree.HTML(text)
    numbers = html.xpath("//div[@class='col-md-1']/text()")
    write_numbers = []
    totle = 0
    for number in numbers:
        write_numbers.append(str(int(number)))
        totle += int(number)
    # print(write_numbers) 这里主要为了写入文件,防止出现问题,实际的图在代码后
    with open(f"./nos.csv", "a+", encoding='utf-8') as f:
        f.write(','.join(write_numbers)+'\t page '+str(page)+' \n')

    return totle


def run():
    headers = {
        'User-Agent': 'Mozilla/5.0 填写你自己的UA',
        'Cookie': 'glidedsky_session=填写你自己的Cookie'
    }

    # 定义一个起始页码
    ips = get_one_ip()  # 获取到IP,我使用的平台一次会返回5个IP,所以下面部分判断是按照数字5进行区分的
    ip_index = 0  # ip序号范围,0~4
    page_index = 1 # 页码
    COUNT = 0 # 计算最终的结果
    while True:

        proxies = {'http': ips[ip_index],
                   'https': ips[ip_index]}  # 从0开始
        print(proxies) # 打印一下IP
        url = f'http://glidedsky.com/level/web/crawler-ip-block-1?page={page_index}' # 从第1页开始爬取
        print("正在抓取:" + url)
        try:
            res = requests.get(
                url, headers=headers, proxies=proxies, timeout=3)  # 通过代理爬取
            text = res.text
            print(f"正在计算第:{page_index} 页")

            totle = calc(text, page_index)
            print("当前的totle值为:"+str(totle))
            # 此处有时没有计算到totle的值,需要在重新抓取数据
            if totle == 0:
                if ip_index < 4:
                    ip_index += 1  # 序号增加
                else:
                    ips = get_one_ip() # IP使用完毕,重新获取
                    ip_index = 0 # 序号从0继续开始
            else:
                COUNT += totle
                print("计算完毕,目前的结果为:"+str(COUNT))
                page_index += 1  # 页码增加
                if ip_index < 4:
                    ip_index += 1  # 序号增加
                else:
                    ips = get_one_ip()
                    ip_index = 0
        except Exception as e:
            print(e)
            print(f"./{url} 爬取失败")
            # 重新抓取
            if ip_index < 4:
                ip_index += 1  # 序号增加
            else:
                ips = get_one_ip()
                ip_index = 0


if __name__ == "__main__":
    run()

nos.csv文件截图,注意到数据有时会出现问题,需要做一些调整,在上述代码中也有相应的说明 Python爬虫入门教程 87-100 glidedsky网站爬虫解析,爬虫闯关第一篇 运行效果图 Python爬虫入门教程 87-100 glidedsky网站爬虫解析,爬虫闯关第一篇

4. 最终结果

没有用多线程,因为一个 IP 只能访问一次,本身限制就比较严格了,所以这个地方跑个 10 几分钟得到结果就 OK 了 最终得到结果之后,输入,通过,然后出现了 IP 限制问题 2。下一篇博客在说吧 Python爬虫入门教程 87-100 glidedsky网站爬虫解析,爬虫闯关第一篇

写在后面

glidedsky 网站整体设计的还是比较有意思的,从简单到困难,有一些小门槛,有兴趣的可以研究研究。我们下一篇博客见~