当前位置: 首页 > news >正文

交大论文下载器

原作者地址:

https://github.com/olixu/SJTU_Thesis_Crawler

问题:

http://thesis.lib.sjtu.edu.cn/的学位论文下载系统,该版权保护系统用起来很不方便,加载起来非常慢,所以该下载器实现将网页上的每一页的图片合并成一个PDF。

解决方案

使用PyMuPDF对图片进行合并

修改

在使用过程中发现我的mac python3执行有错,需要修改代码。
修改如下

修改fitz没有convertToPDF方法的问题

在这里插入图片描述

设置超时时间10s,如果超时则break

在这里插入图片描述

只下载电院的论文

在这里插入图片描述

根据题名来查询

在这里插入图片描述

完整代码

# -*- encoding: utf-8 -*-
'''
@File    :   downloader.py
@Time    :   2021/06/27 10:24:10
@Author  :   olixu
@Version :   1.0
@Contact :   273601727@qq.com
@WebSite    :   https://blog.oliverxu.cn
'''# here put the import lib
from __future__ import print_function, unicode_literals
import os
import sys
import time
import random
import json
import shutil
from collections import defaultdict
from urllib.parse import quote
import requests
from lxml import etree
import fitz
from PyInquirer import style_from_dict, Token, promptdef main():"""下载学位论文入口程序:调用方式:python downloader.py --pages '1-2' --major '计算机'"""answers = search_arguments()info_url, pages = arguments_extract(answers)papers = download_main_info(info_url, pages)will_download = confirmation(papers)['confirmation']if will_download:paper_download(papers)else:print('Bye!')def paper_download(papers):jpg_dir = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + "".join(random.sample('zyxwvutsrqponmlkjihgfedcba23429837498234',5))for paper in papers:print(100*'@')paper_filename = paper['year'] + '_' + paper['filename'] + '_' + paper['author'] + '_' + paper['mentor'] + '.pdf'if verify_name(paper_filename):print("论文{}已经存在".format(paper_filename))continueprint("正在下载论文:", paper['filename'])init(jpg_dir=jpg_dir)try:download_jpg(paper['link'], jpg_dir=jpg_dir)merge_pdf(paper_filename, jpg_dir=jpg_dir)except Exception as e:print(e)def search_arguments():style = style_from_dict({Token.Separator: '#cc5454',Token.QuestionMark: '#673ab7 bold',Token.Selected: '#cc5454',  # defaultToken.Pointer: '#673ab7 bold',Token.Instruction: '',  # defaultToken.Answer: '#f44336 bold',Token.Question: '',})questions = [{'type': 'input','name': 'content','message': '请输入你的检索词'}]answers = prompt(questions, style=style)return answersdef arguments_extract(answers):choose_key = {'主题':'topic', '题名':'title', '关键词':'keyword', '作者':'author', '院系':'department', '专业':'subject', '导师':'teacher', '年份':'year'}xuewei = {'硕士及博士':'0', '博士':'1', '硕士':'2'}px = {'按题名字顺序排序':'1', '按学位年度倒排序':'2'}info_url = "http://thesis.lib.sjtu.edu.cn/sub.asp?content={}&choose_key={}&xuewei={}&px={}&page=".format(quote(answers['content']), \'title', \'2', \'1')print(info_url)pages = [1, 1]return info_url, pagesdef confirmation(papers):print("\033[\033[1;32m 检索到了以下{}篇文章\033[0m".format(len(papers)))for i in papers:print('\033[1;31m 题目\033[0m', i['filename'], '\033[1;34m 作者\033[0m', i['author'], '\033[1;36m 导师\033[0m', i['mentor'], '\033[1;35m 年份\033[0m', i['year'])# 这里需要格式化输出对其一下questions = [{'type': 'confirm','message': "确认下载{}篇文章吗?".format(len(papers)),'name': 'confirmation','default': 'True'}]answers = prompt(questions)return answersdef verify_name(paper_filename):if not os.path.exists('./papers'):os.mkdir('./papers')if paper_filename in os.listdir('./papers'):return Truereturn Falsedef init(jpg_dir):"""初始化文件夹路径"""try:shutil.rmtree('./{}/'.format(jpg_dir))print("删除本地{}文件夹".format(jpg_dir))except Exception as e:print(e)try:os.mkdir('./{}/'.format(jpg_dir))print("新建本地{}文件夹".format(jpg_dir))except Exception as e:print(e)def download_main_info(info_url: str, pages: list):papers = []info_url = info_urlheaders = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36'}result = requests.Session()for page in range(pages[0], pages[1]+1):print("正在抓取第{}页的info".format(page))info_url_construction = info_url + str(page)response = result.get(info_url_construction, headers=headers, allow_redirects=False)html = etree.HTML(response.content, etree.HTMLParser())for i in range(2, 22):# 有些是论文保密,所以link需要错误处理info_dict = defaultdict(str)try:# deparment = html.xpath('/html/body/section/div/div[3]/div[2]/table/tr[{}]/td[4]/text()'.format(i))[0]# if deparment != '(030)电子信息与电气工程学院':#     continuefilename = html.xpath('/html/body/section/div/div[3]/div[2]/table/tr[{}]//td[2]/text()'.format(i))[0]author = html.xpath('/html/body/section/div/div[3]/div[2]/table/tr[{}]/td[3]/div/text()'.format(i))[0]mentor = html.xpath('/html/body/section/div/div[3]/div[2]/table/tr[{}]/td[6]/div/text()'.format(i))[0]year = html.xpath('/html/body/section/div/div[3]/div[2]/table/tr[{}]/td[8]/div/text()'.format(i))[0]link = "http://thesis.lib.sjtu.edu.cn/" + html.xpath('/html/body/section/div/div[3]/div[2]/table/tr[{}]/td[9]/div/a[2]/@href'.format(i))[0]info_dict['filename'] = filenameinfo_dict['author'] = authorinfo_dict['mentor'] = mentorinfo_dict['year'] = yearinfo_dict['link'] = linkpapers.append(info_dict)except Exception as e:# print(e)passprint("总共抓取到{}个元数据信息".format(len(papers)))return papersdef download_jpg(url: str, jpg_dir: str):"""下载论文链接为jpg:param url: 阅读全文链接"""url = urlheaders = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36'}result = requests.Session()print("开始获取图片地址")response = result.get(url, headers=headers, allow_redirects=False)url = response.headers['Location']response = result.get(url, headers=headers, allow_redirects=False)url = response.headers['Location']response = result.get(url, headers=headers, allow_redirects=False)url_bix = response.headers['Location'].split('?')[1]url = "http://thesis.lib.sjtu.edu.cn:8443/read/jumpServlet?page=1&" + url_bixresponse = result.get(url, headers=headers, allow_redirects=False)urls = json.loads(response.content.decode())print("已经获取到图片地址")i = 1while(True):try:fig_url = "http://thesis.lib.sjtu.edu.cn:8443/read/" + urls['list'][0]['src'].split('_')[0] + "_{0:05d}".format(i) + ".jpg"response = result.get(fig_url, headers=headers, timeout=10).contentif len(response) < 2000:breakwith open('./{}/{}.jpg'.format(jpg_dir, i), 'wb') as f:f.write(response)i = i + 1print("正在采集第{}页".format(i))except requests.exceptions.Timeout:print("请求超时,退出循环")breakdef merge_pdf(paper_filename, jpg_dir):doc = fitz.open()imgs = []img_path = './{}/'.format(jpg_dir)for img in os.listdir('./{}/'.format(jpg_dir)):imgs.append(img)imgs.sort(key=lambda x:int(x[:-4]))for img in imgs:img_file = img_path + imgimgdoc = fitz.open(img_file)pdfbytes = imgdoc.convert_to_pdf()pdf_name = str(img[:-4]) + '.pdf'imgpdf = fitz.open(pdf_name, pdfbytes)doc.insert_pdf(imgpdf)filename = './papers/' + paper_filenamedoc.save(filename)doc.close()shutil.rmtree('./{}'.format(jpg_dir))if __name__=='__main__':main()

相关文章:

交大论文下载器

原作者地址&#xff1a; https://github.com/olixu/SJTU_Thesis_Crawler 问题&#xff1a; http://thesis.lib.sjtu.edu.cn/的学位论文下载系统&#xff0c;该版权保护系统用起来很不方便&#xff0c;加载起来非常慢&#xff0c;所以该下载器实现将网页上的每一页的图片合并…...

全栈笔记_浏览器扩展篇(manifest.json文件介绍)

manifest.json介绍 是web扩展技术必不可少的插件配置文件,放在根目录作用: 指定插件的基本信息 name:名称manifest_version:manifest.json文件的版本号,可以写2或3version:版本description:描述定义插件的行为: browser_action:添加一个操作按钮到浏览器工具栏,点击按…...

蓝桥杯每日一题(python)

##斐波那契数列的应用 --- 题目斐波那契 题目&#xff1a; 如果数组 A (a0, a1, , an−1) 满足以下条件&#xff0c;就说它是一个斐波那契数组&#xff1a; 1. n ≥ 2&#xff1b; 2. a0 a1&#xff1b; 3. 对于所有的 i(i ≥ 2)&#xff0c;都满足 ai ai−1 ai−2…...

【Vue】工程化开发脚手架Vue CLI

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Vue⛺️稳重求进&#xff0c;晒太阳 工程化开发&脚手架Vue CLI 基本介绍 Vue Cli是Vue官方提供的一个全局命令工具 可以帮助我们快速创建一个开发Vue项目的标准化基础架子【集成了we…...

嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第三天-ARM Linux ADC和触摸屏开发 (物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1V0E9IHSoLbpiWJsncmFgdA?pwd1688 提取码&#xff1a;1688 教学内容&#xff1a; 1、ADC S3C2440的A/D转换器包含一个8通道的模拟输入转换器&#xff0c;可以将模拟输入信号转换成10位数字编码。 在A/D转换时钟频率为2.5MHz时&…...

LeetCode “AddressSanitizer:heat-use-after-free on address“问题解决方法

heat-use-after-free &#xff1a; 访问堆上已经被释放的内存地址 现象&#xff1a;同样代码在LeetCode上报错&#xff0c;但是自己在IDE手动打印并不会报错 个人猜测&#xff0c;这个bug可能来源于LeetCode后台输出打印链表的代码逻辑问题。 问题描述 题目来自LeetCode的8…...

幸运彩票

L1-6 幸运彩票 分数 15 作者 陈越 单位 浙江大学 彩票的号码有 6 位数字&#xff0c;若一张彩票的前 3 位上的数之和等于后 3 位上的数之和&#xff0c;则称这张彩票是幸运的。本题就请你判断…...

搭建yum仓库服务器

安装 1.安装linux 1.1安装依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 1.2下载 cd /opt/nginx wget http://nginx.org/download/nginx-1.25.3.tar.gz 1.3解压 tar -xvf nginx-1.25.3.tar.gz 1.4配置 cd nginx-1.25.3 ./configure --pre…...

贪心算法练习day1

练习1--翻硬币 1&#xff09;题目及要求 2&#xff09;解题思路 输入的是字符串&#xff0c;要想将两组字符串进行一一对比&#xff0c;需要将字符串转换成字符数组&#xff0c;再使用for循环依次遍历字符数组&#xff0c;进行比对。 输入两行字符串&#xff0c;转换成两个字…...

[VulnHub靶机渗透] WestWild 1.1

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…...

如何使用 ControlValueAccessor 在 Angular 中创建自定义表单控件

简介 在 Angular 中创建表单时&#xff0c;有时您希望拥有一个不是标准文本输入、选择或复选框的输入。通过实现 ControlValueAccessor 接口并将组件注册为 NG_VALUE_ACCESSOR&#xff0c;您可以将自定义表单控件无缝地集成到模板驱动或响应式表单中&#xff0c;就像它是一个原…...

视频讲解:优化柱状图

你好&#xff0c;我是郭震 AI数据可视化 第三集&#xff1a;美化柱状图&#xff0c;完整视频如下所示&#xff1a; 美化后效果前后对比&#xff0c;前&#xff1a; 后&#xff1a; 附完整案例源码&#xff1a; util.py文件 import platformdef get_os():os_name platform.syst…...

OpenAI宣布ChatGPT新增记忆功能;谷歌AI助理Gemini应用登陆多地区

&#x1f989; AI新闻 &#x1f680; OpenAI宣布ChatGPT新增记忆功能&#xff0c;可以自由控制内存&#xff0c;提供个性化聊天和长期追踪服务 摘要&#xff1a;ChatGPT新增的记忆功能可以帮助AI模型记住用户的提问内容&#xff0c;并且可以自由控制其内存。这意味着用户不必…...

Solidworks:平面草图练习

继续练习平面草图&#xff0c;感觉基本入门了。...

React18原理: 渲染与更新时的重点关注事项

概述 react 在渲染过程中要做很多事情&#xff0c;所以不可能直接通过初始元素直接渲染还需要一个东西&#xff0c;就是虚拟节点&#xff0c;暂不涉及React Fiber的概念&#xff0c;将vDom树和Fiber 树统称为虚拟节点有了初始元素后&#xff0c;React 就会根据初始元素和其他可…...

嵌入式I2C 信号线为何加上拉电阻(图文并茂)

IIC 是一个两线串行通信总线&#xff0c;包含一个 SCL 信号和 SDA 信号&#xff0c;SCL 是时钟信号&#xff0c;从主设备发出&#xff0c;SDA 是数据信号&#xff0c;是一个双向的&#xff0c;设备发送数据和接收数据都是通过 SDA 信号。 在设计 IIC 信号电路的时候我们会在 SC…...

Vite 5.0 正式发布

11 月 16 日&#xff0c;Vite 5.0 正式发布&#xff0c;这是 Vite 道路上的又一个重要里程碑&#xff01;Vite 现在使用 Rollup 4&#xff0c;这已经代表了构建性能的大幅提升。此外&#xff0c;还有一些新的选项可以改善开发服务器性能。 Vite 4 发布于近一年前&#xff0c;它…...

嵌入式STM32 单片机 GPIO 的工作原理详解

STM32的 GPIO 介绍 GPIO 是通用输入/输出端口的简称&#xff0c;是 STM32 可控制的引脚。GPIO 的引脚与外部硬件设备连接&#xff0c;可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 以 STM32F103ZET6 芯片为例子&#xff0c;该芯片共有 144 脚芯片&#xff0c…...

系统调用的概念

在嵌入式开发、操作系统开发以及一般的系统编程中&#xff0c;系统调用是一个核心概念。它允许用户空间程序请求内核执行某些操作&#xff0c;如打开文件、读写数据、创建进程等。这些操作通常需要特殊的权限或访问硬件资源&#xff0c;因此不能直接在用户模式下执行。 系统调…...

【无标题】Matlab 之axes函数——创建笛卡尔坐标区

**基本用法&#xff1a;**axes 在当前图窗中创建默认的笛卡尔坐标区&#xff0c;并将其设置为当前坐标区。 应用场景1&#xff1a;在图窗中放置两个 Axes 对象&#xff0c;并为每个对象添加一个绘图。 要求1&#xff1a;指定第一个 Axes 对象的位置&#xff0c;使其左下角位于…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...