最近由于需要帮朋友找人教版初中地理教材pdf资料,人教出版社官方提供了七年级下册和八年级下册的pdf资源,上册需要自己想办法啦!经过一番信息检索,发现搜狐上居然有提供我想要的版本教材扫描版,果断下载呀!可是在下载过程中遇到了许多问题,下面讲述一下本次资源获取艰辛之路
网页打印pdf
搜狐提供教材图片版,第一想法当然是将网页打印成pdf,可是网页上还有许多杂七杂八的东西是我不需要的,不过这可难不倒我,在浏览器审查元素的支持下,我将不需要的内容全部删除啦,并且,简单加几条css规则,这样就可以打印成pdf了呗,事实证明这是可行的,但是有一点小小的瑕疵,新的pdf一页内容和原来的教材一页内容对不上,意味着原来的一页可能在这里就被分成上下两截。作为强迫症患者的我当然不能忍受这个,于是开始了进阶尝试。
保存网页
想法很简单,将整个网页保存下来,这样不就所有的图片都下载好了吗!说干就干,直接一个Ctrl+S
,我看到了一个放满了图片的文件夹,每一张图片就是一页教材,真是太完美了。No!一点儿也不美丽,每一张图片都是一串乱七八糟的字符命名,根本没有顺序可言,那我怎么将这堆图片合并成一个pdf呢,难道要我每张图片根据页面重命名一下?不不不,这种活儿我可不会干!
python爬虫
既然半自动保存图片失败了,那就上全自动保存图片。对于一个坚决不做机械式重复劳动的不折腾会死星人,让我每张图片重命名一次,和直接在网页上一张一张图片下载有什么区别呢?可别忘了自己还有技能树呢!对于这种任务,直接上python
,两个包requests+lxml
是我的最爱,打开我的vscode,两下半就完成一个爬虫,运行一下,所有的教材图片有序躺在我的文件夹中,完全不用自己重命名排个序什么的。
合成pdf
最后说一下如何将这堆图片打包成一个pdf,有同学可能想到了新建一个空白word,然后插入所有图片,最后导出pdf。不得不承认,这是可行的方法,但不是最优的方法。条条大路通罗马,当然要选择一条平坦的捷径咯,打开福昕高级版PDF编辑器,创建,合并文件,然后选择图片的整个文件夹,点击合并即可!
附录
import time
import logging
from pathlib import Path
from lxml import etree
import requests
def create_logger(loggername:str='logger', levelname:str='DEBUG', console_levelname='INFO'):
levels = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
logger = logging.getLogger(loggername)
logger.setLevel(levels[levelname])
logger_format = logging.Formatter("[%(asctime)s][%(levelname)s][%(filename)s][%(funcName)s][%(lineno)03s]: %(message)s")
console_format = logging.Formatter("[%(levelname)s] %(message)s")
handler_console = logging.StreamHandler()
handler_console.setFormatter(console_format)
handler_console.setLevel(levels[console_levelname])
# path = Path(__file__).parent/'logs' # 日志目录
path = Path('./logs')
path.mkdir(parents=True, exist_ok=True)
today = time.strftime("%Y-%m-%d") # 日志文件名
common_filename = path / f'{today}.log'
handler_common = logging.FileHandler(common_filename , mode='a+', encoding='utf-8')
handler_common.setLevel(levels[levelname])
handler_common.setFormatter(logger_format)
logger.addHandler(handler_console)
logger.addHandler(handler_common)
return logger
logger = create_logger('Crawler')
class Crawler:
def __init__(self, url, path):
self.url = url
self.path = Path(path)
self.path.mkdir(parents=True, exist_ok=True) # 安全创建目录
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362"
}
def _download(self, url, filename):
try:
resp = requests.get(url)
except:
logger.debug(f'请求异常')
if 200 != resp.status_code:
logger.debug(f'请求失败')
with filename.open('wb') as fp:
fp.write(resp.content)
logger.info(f'完成下载{filename} {url}')
def cycle(self):
try:
resp = requests.get(self.url, headers=self.headers)
except:
logger.debug(f'请求异常')
if 200 != resp.status_code:
logger.debug(f'请求失败')
try:
html = etree.HTML(resp.text)
except:
logger.debug(f'转换异常')
imgs = html.xpath('//article[@id="mp-editor"]/p/img/@src')
for (idx, img) in enumerate(imgs):
filename = self.path/f'{idx:03}.jpg'
logger.info(f'准备下载{filename} {img}')
self._download(img, filename)
if __name__ == "__main__":
# url = "https://www.sohu.com/a/240462346_796524" # 人教版地理教材八年级上册
# url = "https://www.sohu.com/a/240462516_796524" # 人教版地理教材七年级上册
# path = './images'
logger.info(f'欢迎使用搜狐图片下载器')
logger.info(f'如:人教版地理教材八年级上册 "https://www.sohu.com/a/240462346_796524"')
url = input(f'请输入目标网址: ')
path = input(f'请输入保存路径: ')
crawler = Crawler(url, path)
crawler.cycle()