交大论文下载器

原作者地址:

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, prompt

def 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))
            continue
        print("正在下载论文:", 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',  # default
                Token.Pointer: '#673ab7 bold',
                Token.Instruction: '',  # default
                Token.Answer: '#f44336 bold',
                Token.Question: '',
                })

    questions = [
        {
            'type': 'input',
            'name': 'content',
            'message': '请输入你的检索词'
        }
    ]
    answers = prompt(questions, style=style)
    return answers

def 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, pages

def 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 answers

def verify_name(paper_filename):
    if not os.path.exists('./papers'):
        os.mkdir('./papers')
    if paper_filename in os.listdir('./papers'):
        return True
    return False

def 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_url
    headers = {
        '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)电子信息与电气工程学院':
                #     continue
                filename = 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'] = filename
                info_dict['author'] = author
                info_dict['mentor'] = mentor
                info_dict['year'] = year
                info_dict['link'] = link
                papers.append(info_dict)
            except Exception as e:
                # print(e)
                pass
    print("总共抓取到{}个元数据信息".format(len(papers)))
    return papers

def download_jpg(url: str, jpg_dir: str):
    """下载论文链接为jpg
        :param url: 阅读全文链接
    """
    url = url
    headers = {
        '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_bix
    response = result.get(url, headers=headers, allow_redirects=False)
    urls = json.loads(response.content.decode())
    print("已经获取到图片地址")
    i = 1

    while(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).content
            if len(response) < 2000:
                break
            with open('./{}/{}.jpg'.format(jpg_dir, i), 'wb') as f:
                f.write(response)
            i = i + 1
            print("正在采集第{}页".format(i))
        except requests.exceptions.Timeout:
            print("请求超时,退出循环")
            break

def 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 + img
        imgdoc = 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_filename
    doc.save(filename)
    doc.close()
    shutil.rmtree('./{}'.format(jpg_dir))

if __name__=='__main__':
    main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/390222.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[ai笔记7] google浏览器ai学习提效定制优化+常用插件推荐

欢迎来到文思源想的ai空间&#xff0c;这是技术老兵重学ai以及成长思考的第7篇分享&#xff01; 工欲善其事必先利其器&#xff0c;为了ai学习的效能提升&#xff0c;放假期间对google浏览器做了一次系统整改&#xff0c;添加了一些配置和插件&#xff0c;这里既有一些显示、主…

离散数学截图2

为什么G中阶大于2的元素&#xff0c;一定有偶数个 在有限群G中&#xff0c;阶大于2的元素个数一定是偶数的原因如下&#xff1a; 设 aaa 是群G中一个阶大于2的元素&#xff0c;那么根据群的定义和阶的概念&#xff08;即某个元素的幂次使得其等于单位元的最小正整数&#xff…

防御保护--内容安全过滤

目录 文件过滤 内容过滤技术 邮件过滤技术 应用行为控制技术 DNS过滤 URL过滤 防火墙 ---- 四层会话追踪技术 入侵防御 ---- 应用层深度检测技术 深度包检测深度流检测 随着以上俩种的成熟与完善&#xff0c;提出了所谓的内容安全过滤 当然上网行为确实需要治理&…

【html学习笔记】2.基本元素

1.标题 标题会自动粗体其中大写的内容&#xff0c;并带有换行的效果会使用<h1>到<h6>表示不同大小的标题 <h1>标题1</h1> <h2>标题2</h2> <h3>标题3</h3> <h4>标题4</h4> <h5>标题5</h5> <h6>…

NumPyML 源码解析(七)

numpy-ml\numpy_ml\trees\gbdt.py # 导入 numpy 库并重命名为 np import numpy as np# 从当前目录下的 dt 模块中导入 DecisionTree 类 # 从当前目录下的 losses 模块中导入 MSELoss 和 CrossEntropyLoss 类 from .dt import DecisionTree from .losses import MSELoss, Cross…

java8新特性——StreamAPI

说明&#xff1a; java8中有两大最为重要的改变。第一个是Lambda表达式&#xff1b;另外一个则是Stream API。 Stream API&#xff08;java.util.stream&#xff09;把真正的函数式编程风格引入java。这是目前为止对java类库最好的补充&#xff0c;因为Stream API可以极大提供j…

基于微信小程序的在线课堂的研究与实现,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

Codeforces Round 926 (Div. 2) B. Sasha and the Drawing (Java)

Codeforces Round 926 (Div. 2) B. Sasha and the Drawing (Java) 比赛链接&#xff1a;Codeforces Round 926 (Div. 2) B题传送门&#xff1a;B. Sasha and the Drawing 题目&#xff1a;B. Sasha and the Drawing Example input 3 4 3 3 3 10 3 9 4 7 7 11 2 3output 2 …

VMware Workstation 17.0 虚拟机安装MS-DOS 7.1完整详细步骤图文教程

VMware Workstation 17.0 虚拟机安装MS-DOS 7.1完整详细步骤图文教程 一、配置MS-DOS虚拟机机器环境二、安装MS-DOS磁盘操作系统 一、配置MS-DOS虚拟机机器环境 1.打开VMware Workstation Pro 2.新建虚拟机 3.建议选择【典型】&#xff0c;之后点击【下一步】 关于【自定义…

前端秘法基础式(CSS)(第一卷)

一.认识CSS CSS 指的是层叠样式表&#xff08;Cascading Style Sheets&#xff09;&#xff0c;它是一种用于描述网页外观和布局的语法 CSS 可以定义网页中元素的字体、颜色、大小、位置、背景等样式&#xff0c;使网页具有美观的外观和统 一的风格。 通过将 CSS 样式表与 HTML…

Qt Creator 继承分文件编写代码流程实现简单案列

Qt Creator 继承分文件流程实现简单案列 打开Qt Creator&#xff0c;新建c项目 添加类 完成之后&#xff0c;会自动生成.h和.cpp文件 一、animal.h文件 主要用来写类&#xff0c;包括成员变量和函数 #ifndef ANIMAL_H #define ANIMAL_H #include <iostream> #inclu…

C#上位机与三菱PLC的通信04--MC协议之A-1E报文测试

到目前为止&#xff0c;还没有网上有哪个文章有我如此的报文分析&#xff0c;操作实例&#xff0c;一大批都是抄来抄去&#xff0c;没有截图&#xff0c;没有说明&#xff0c;没有实例&#xff0c;有卵用呀&#xff0c;仅以此文章献给最爱的粉丝&#xff0c;希望对各位大师有些…

vue3 之 商城项目—结算模块

路由配置 chekout/index.vue <script setup> const checkInfo {} // 订单对象 const curAddress {} // 地址对象 </script> <template><div class"xtx-pay-checkout-page"><div class"container"><div class"w…

lenovo联想小新 Pro14 2022 Intel版IAH5R,AMD版ARH5R(82UT),(82UU)原装出厂Win11系统带恢复重置功能

联想小新Pro14笔记本电脑恢复原厂OEM预装Windows11系统镜像包&#xff0c;开箱状态时一模一样 Intel版(82UT)链接&#xff1a;https://pan.baidu.com/s/1jexQXkC6TerUnDQffwLooA?pwdcc09 提取码&#xff1a;cc09 AMD锐龙版(82UU)链接&#xff1a;https://pan.baidu.com/s/…

【FPGA开发】HDMI通信协议解析及FPGA实现

本篇文章包含的内容 一、HDMI简介1.1 HDMI引脚解析1.2 HDMI工作原理1.3 DVI编码1.4 TMDS编码 二、并串转换、单端差分转换原语2.1 原语简介2.2 IO端口组件 笔者在这里使用的开发板是正点原子的达芬奇开发板&#xff0c;FPGA型号为XC7A35TFGG484-2。参考的课程是正点原子的课程手…

Calendar的使用(Java)

直接从需求来理解&#xff1a;将2024年2月16日增加一个月 如果不使用Calendar的话&#xff0c;我们需要定义字符串记住这个日期&#xff0c;然后把字符串解析成Date日期对象&#xff0c;通过Date日期对象获取其毫秒值&#xff0c;然后增加一个月的毫秒值&#xff0c;再格式化时…

蓝桥杯第十四届电子类单片机组程序设计

目录 前言 蓝桥杯大赛历届真题&#xff08;点击查看&#xff09; 一、第十四届比赛题目 1.比赛原题 2.题目解读 1&#xff09;任务要求 2&#xff09;注意事项 二、任务实现 1.NE555读取时机的问题 1&#xff09;缩短计数时间 2&#xff09;实时读取 2.温度传感器读…

社区养老|社区养老服务系统|基于springboot社区养老服务系统设计与实现(源码+数据库+文档)

社区养老服务系统目录 目录 基于springboot社区养老服务系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员部分功能 &#xff08;1&#xff09; 用户管理 &#xff08;2&#xff09;服务种类管理 &#xff08;3&#xff09;社区服务管理 &#xff08…

MySQL 基础知识(八)之用户权限管理

目录 1 MySQL 权限管理概念 2 用户管理 2.1 创建用户 2.2 查看当前登录用户 2.3 修改用户名 2.4 删除用户 3 授予权限 3.1 授予用户管理员权限 3.2 授予用户数据库权限 3.3 授予用户表权限 3.4 授予用户列权限 4 查询权限 5 回收权限 1 MySQL 权限管理概念 关于 M…

NodeJS背后的人:Express

NodeJS背后的人&#xff1a;Express 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2; 文章简单学习总结&#xff1a;如有错误 大佬 &#x1f449;点. 前置知识&#xff1a;需要掌握了解&#xff1a; JavaScript基础语法 、Node.JS环境API 、前端工程\模块化 …