首页 > 其他分享 >国家中小学智慧教育平台教材PDF下载爬虫

国家中小学智慧教育平台教材PDF下载爬虫

时间:2023-12-13 10:25:42浏览次数:28  
标签:info get url 爬虫 json book books PDF 中小学

一、确定目标网站

image

二、目标数据分析

2.1 查看目标数据

点击教材后,发现需要登录,如下图。
image
注册登录后查看,同时打开DevTools记录数据包,发现教材PDF下载链接,但无法直接下载,如下图。
image
网上搜索相关话题后发现可通过更改URL绕过该限制,经测试可行,如下图。
image

2.2 爬取思路

既然找到了实际下载链接,那么只需要再找到所有教材PDF的ID即可,有两种思路。

  1. 找到相关数据集请求包,直接拿到所有ID或者下载链接;
  2. 使用selenium逐个点击教材获取地址栏的文件ID,之后使用requests下载。

三、实际爬取

3.1 使用selenium爬取文件ID

由于未登录看不到教材内容,所以我测试时均登录了账号,但是经过反复抓包均未看到相关数据集请求(后证实和缓存有关,尽管我在DevTools中设置了禁用缓存)。所以先采用selenium爬取文件ID的方法。
image
由于科目众多,所以我们需要使用循环嵌套的形式遍历所有教材,结构如下图所示。
image
经过上面4层嵌套后,再获取当前页面下教材列表,逐个点击获取教材ID即可。
因为每次点击都会打开新标签页,我们可以使用selenium.webdriver.switch_to.window(window_handle)的方法切换到新标签页,然后调用close()方法后再切换回去。这样就避免了大量标签页带来的内存消耗。
由于后面有更好的方法,这里就不放代码了。

3.2 使用requests获取所有教材PDF

在经历了DevTools源代码搜索,JS断点调试,Burpsuite代理逐项通过请求等方法尝试找出数据集请求均未果后,我在无痕模式中重新打开教材链接,意味发现了数据接口相关请求,真可谓踏破铁鞋无觅处,得来全不费功夫。如下图所示。
image
xhr请求有三个,链接不完全相同,那么肯定有请求可以获取到这三个文件的的地址,经搜索可以定位到。如下图所示。
image
至此,我们便得到了所有需要的信息,按照以下步骤编写代码即可。

  1. 访问入口文件获取数据请求API;
  2. 访问数据请求API获取所有文件信息;
  3. 构造教材PDF链接进行下载。
"""
@filename=main.py
@version=0.1.0.20231212
@author=amnotgcs
@createTime=20231212 19:01
@lastModifiedTime=20231212 20:43
@description=爬取国家中小学智慧教育平台所有教材PDF
@target.url=https://basic.smartedu.cn/tchMaterial
"""


import json

import requests
import pandas as pd


# 数据文件获取链接
ENTRY_URL = 'https://s-file-2.ykt.cbern.com.cn/zxx/ndrs/resources/tch_material/version/data_version.json'
HEADER = {
    'Accept': 'application/json, text/plain, */*',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
    'Referer': 'https://basic.smartedu.cn/',
}
TIMEOUT = 3
JSON_FILENAME = 'books_info.json'  # JSON结果文件名
XLSX_FILENAME = 'books_info.xlsx'  # XLSX结果文件名


def get_data_json_url() -> list[str]:
    """访问数据文件获取链接,获取数据URL"""
    data_json_url = requests.get(ENTRY_URL, headers=HEADER, timeout=TIMEOUT).json()
    if result := data_json_url.get('urls'):
        return result.split(',')
    return []


def get_books_info(url: str) -> list[dict]:
    "访问数据URL,获取所有图书的信息"
    response = requests.get(url, headers=HEADER, timeout=TIMEOUT)
    if response.status_code == 200:
        return response.json()
    return []
    

def retrieve_all_books() -> list[dict]:
    """获取平台所有教材PDF"""
    books = []
    for data_json_url in get_data_json_url():
        books.extend(get_books_info(data_json_url))
    for book in books:
        book_id = book.get('id')
        book_url = f'https://r3-ndr.ykt.cbern.com.cn/edu_product/esp/assets/{book_id}.pkg/pdf.pdf'
        book['pdf_url'] = book_url
        # TODO(amnotgcs): 此处未实际下载pdf,根据个人需要进行下载即可。
        # 样例代码:
        # pdf = requests.get(book_url, headers=HEADER)
        # with open(f'{book_id}.pdf', 'wb') as file:
        #     file.write(pdf.content)
        print('正在下载:', book_url)
    return books


def save_books_info(books: list[dict]) -> None:
    """将PDF信息保存到文件"""
    # 提取需要的信息
    book_info_for_save = []
    for book in books:
        book_info = {}
        for item in ['id', 'title', 'language', 'resource_type_code', 'create_time', 'update_time', 'pdf_url']:
            book_info[item] = book.get(item)
        for item in ['resolution', 'size', 'width']:
            book_info[item] = book.get('custom_properties').get(item)
        book_info['tag'] = '/'.join([tag.get('tag_name') for tag in book.get('tag_list')])
        book_info_for_save.append(book_info)
    # 保存为JSON格式
    with open(JSON_FILENAME, 'wt', encoding='UTF-8') as file:
        json.dump(book_info_for_save, file, ensure_ascii=False, indent=4)
    # 保存为xlsx格式
    book_info_df = pd.read_json(JSON_FILENAME)
    # 去除时区信息以便存为xlsx
    book_info_df['create_time'] = book_info_df['create_time'].dt.tz_localize(None)
    book_info_df['update_time'] = book_info_df['update_time'].dt.tz_localize(None)
    book_info_df.to_excel(XLSX_FILENAME)


if __name__ == '__main__':
    books = retrieve_all_books()
    save_books_info(books)

【说明】因为headers中'Accept-Encoding': 'gzip, deflate, br'指明了可以使用br压缩算法,所以需要pip安装brotli库,否则可能会有乱码问题。如果不想安装,去除headers中的br亦可。

标签:info,get,url,爬虫,json,book,books,PDF,中小学
From: https://www.cnblogs.com/amnotgcs/p/17898415.html

相关文章

  • 爬虫
    一、请用requests库的get()函数访问如下一个网站20次,打印返回状态,text()内容,计算text()属性和content属性所返回网页内容的长度。(不同学号选做如下网页,必做及格)importrequestsfrombs4importBeautifulSoupurl='https://baidu.com'foriinrange(20):try:r=requests......
  • 【专题】中国餐饮业数字化发展报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=34529原文出处:拓端数据部落公众号餐饮业作为实体经济的重要组成部分,对于促进经济增长、刺激消费、增加就业和改善民生具有十分重要的作用。随着全球科技革命和产业变革的加速推进,数字化转型已成为产业发展的必然趋势,其中大数据、物联网、人工智能......
  • Quick BI 数据分析 - Alibaba Cloud的文档PDF
     下载地址:https://static-aliyun-doc.oss-cn-hangzhou.aliyuncs.com/download%2Fpdf%2F164487%2F%25E6%2595%25B0%25E6%258D%25AE%25E5%2588%2586%25E6%259E%2590_intl_zh-CN.pdf      ......
  • 【Python爬虫】爬虫框架Scrapy初使用_爬取4399游戏页面数据
    Scrapy简介Scrapy是一个用于爬取和提取数据的开源web抓取框架。它提供了一个强大的机制,让开发者可以轻松地创建和管理爬虫程序,以从网站上自动提取结构化的数据。以下是Scrapy的一些主要特点和优势:强大灵活的爬取能力:Scrapy具有高度可配置的请求处理和数据提取功能。它可以轻......
  • 解决Python爬虫中Header报错的方法
    在使用Python编写爬虫时,有时会遇到Header报错的情况。本文将介绍常见的Header报错类型,并提供解决方法,帮助您顺利处理Python爬虫中的Header报错问题。当我们使用Python进行爬虫开发时,经常需要设置请求头(Header)来模拟浏览器发送请求。然而,有时可能会遇到一些与Header相关的报错。以下......
  • Python爬虫无法获取页面内容的常见原因及解决方法
     在使用Python进行网页爬取时,有时会遇到无法获取页面内容的情况。本文将探讨造成这种情况的常见原因,并提供一些解决方法,帮助您顺利进行网页内容的爬取。 当我们使用Python进行网页爬取时,有时会遇到无法获取页面内容的情况。以下是可能导致这种情况的常见原因: 1.请求错误: 在构......
  • 微信公众号文章批量转pdf
    操作步骤步骤一:下载离线html网页文件1、登录微信公众号后台,打开“发表记录”。2、按Ctrl+S或右击网页选择“另存为”,保存离线的html网页文件。(网页的文件后缀名是html)3、记住html文件保存路径(如下图最上面红色方框),并设置【html文件名称】。注意:html文件由序号1~n,html文件名称格......
  • pdf.js打开后的pdf文件
    原文链接:https://www.cnblogs.com/the-big-dipper/p/16880180.html 1、html项目方法:<ahref="../../pdf/web/viewer.html?file=../../pdf/1.pdf"target="_blank">文件</a>最重要的是href的地址。href地址的组成:pdfjs的viewer.html地址 + ?file=+ pdf文件地址pdfjs......
  • Java开发者的Python快速实战指南:实用工具之PDF转DOCX文档(可视化界面)
    首先,大家对Python语法的了解已经基本完成,现在我们需要开始进行各种练习。我为大家准备了一些练习题目,比如之前的向量数据库等,这些题目可以参考第三方的SDK来进行操作,文档也是比较完善的。这个过程有点像我们之前使用Java对接第三方接口的方式,所以今天我想开发一个很实用的工具类,用......
  • 多线程爬虫抓取京东运行流程-大公司抢着要代码
    之前有个大公司找我,需要爬取京东有关行业商家的价格信息做对比,方便后期自己的产品定位以及舆情监控,让我写一个通用的爬虫模版,方便他们那边技术调整修改,于是带着这样的问题,我给了他们一些几点建议。首先,你需要安装必要的库,包括HTTP库、JSON库、爬虫库、代理库和可视化库。可以使......