Python爬取蓝桥杯真题讲解课程


今年疫情期间蓝桥杯课程全线免费,但是如果每次听课都要登录账号实在太麻烦了,所以想着用爬虫抓去一下视频到本地。

环境配置

这次我们用re、requests、urllib这三个库来提取。

构造请求头

我们需要安装Chrome浏览器,进入浏览器 Ctrl+Shift+I 呼出开发者工具。接着打开网址:http://weike.lanqiao.cn/
找到如图所示的User-Agent:
请求头代码如下:
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
后面代码会用到。

请求访问网页

def get_html(url):
    headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
               'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        return response.text
    else:
        return
 response = requests.get(url, headers=headers)

使用 requests 库的 get 方法去访问网页,第一个参数为网址,第二个参数为请求头,请求结果赋值给变量 response,其中里面有很多结果、状态响应码、网页源码、二进制等。

response.status_code == 200

调用请求结果 response 中的 status_code 查看请求状态码,200 代表请求成功,就返回,否则返回一个 None,状态码一般有 2xx,4xx,3xx,5xx,分别代表请求成功,客户端访问失败,重定向,服务器问题。

return response.text

返回响应结果的 text,代表返回网页 html 源码

获取数据
我通过开发者工具检查网页源码,如下图所示:

红线部分的就是视频的链接,通过观察链接与链接只有最后的汉字部分不同,我们书写正则表达式:

pat = '<source src="../sources/(.*?)" type="video/mp4">'

其中只有(.?)里的汉字标题内容不同,(.?)内的内容会赋值给pat。

    titles = re.findall(pat,str(html),re.S)
    for title in titles:
        title = parse.quote(title,'+')

titles里存放的是这个网页所有的汉字标题,由于我们最终要得到的是可以下载的直接链接,我们对汉字进行编码。

编码函数:quote(string, safe)

除了三个符号“_.-”不编码,后面的参数safe是添加不编码的字符。

批量URL

     Chinese_num = ['一', '二', '三', '四', '五', '六']
    id = ['1102','1103','1104','1105','1106','1497']
    urls = ['http://weike.lanqiao.cn/static/coursehuifang/LNZTC++A/content/第{}节{}年省赛真题详解.html?courseid=19&dayclassid={}'
                .format(num, str(i), j) for num, i, j in zip(Chinese_num, range(2013, 2019),id)]
    for url in urls:
        url = parse.quote(url, '=/:+?&')
        html = get_html(url)
        get_infos(html)
        time.sleep(1)

这里主要就看每一年真题链接的规律,觉得麻烦的可以一个一个链接手动输入。毕竟一共就6年真题6个链接。
这个zip函数,意思是把三个元素打包,可以这样理解 zip 函数的结果是一个列表 [(num,i,j)],每一次循环的 num,i,j 一次对应元组中的元素。range函数取不到最后一个数字所以是2019,实际只会取到2018。

完整代码

# 蓝桥杯课程
import re
import time
import requests
from urllib import parse

def get_html(url):
    headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
    'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        response.encoding = 'utf-8'
        return response.text
    else:
        return

def get_infos(html):
    pat = '<source src="../sources/(.*?)" type="video/mp4">'
    # 要爬取内容的正则表达式,观察url只有(.*?)里的标题内容不同,pat=(.*?)。
    titles = re.findall(pat,str(html),re.S)
    for title in titles:
        title = parse.quote(title,'+')
    # quote(string, safe),除了三个符号“_.-”不编码,后面的参数safe是添加不编码的字符。
        print("http://weike.lanqiao.cn/static/coursehuifang/LNZTC++C/sources/"+title)

def main():
    Chinese_num = ['一', '二', '三', '四', '五', '六']
    id = ['1102','1103','1104','1105','1106','1497']
    urls = ['http://weike.lanqiao.cn/static/coursehuifang/LNZTC++A/content/第{}节{}年省赛真题详解.html?courseid=19&dayclassid={}'
                .format(num, str(i), j) for num, i, j in zip(Chinese_num, range(2013, 2019),id)]
    for url in urls:
        url = parse.quote(url, '=/:+?&')
        html = get_html(url)
        get_infos(html)
        time.sleep(1)

# if __name__ == '_main_':
if __name__ == '__main__':
    main()


这里建议使用IDM批量下载速度很快。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM