从 chinadaily 下载 chinadail 的 pdf papger,chinadailpapger,之前刚开始用 apach
从 chinadaily 下载 chinadail 的 pdf papger,chinadailpapger,之前刚开始用 apach
之前刚开始用 apache http 包的时候弄了个 java 版的,用来下载下来后复习一下 e文,后来丢了。最近在学python,就趁机弄了个python版本的,用来练练手。注意:需要python3.2.3(最前最新)或以上的版本,主要是3.2.3以下对 post 后的 redirect 会出现异常,FancyURLopener 倒没有这个问题,但python文档说,FancyURLopener 是遗留资产,将来可能会废弃,所以这里也没有用。
程序代码
# -*- coding: utf-8 -*-'''因为涉及到post的redirect问题,需要python 3.2.3及以上版本'''import configparser;from urllib import request;from urllib import parse;from datetime import date;from datetime import timedelta;from datetime import datetime;import struct;import os;from os import path;def readConfig(confName = 'chinadaily.ini'): ''' 读取配置文件 chinadaily.ini,获取用户名,密码等 @param confName 配置文件的默认文件名 ''' conf = configparser.ConfigParser(); conf.read(confName); return conf['DEFAULT'];def login(conf): ''' 登录chinadaily @param conf 配置文件 @return 登录是否成功,不成功时抛出异常 ''' # 登录用户名和密码 loginData = parse.urlencode({'email': conf.get('username'), 'password':conf.get('password')}).encode(conf.get('encoding')); loginReq = request.Request(conf.get('loginPost'), loginData); loginedPage = request.urlopen(loginReq); # TODO:判断是否登录成功 return True;def downADay(conf, targetDate): ''' 下载指定日期的chinadaily pdf 文件 @param conf 配置信息 @param targetDate 要下载的日期 ''' weekday = targetDate.isoweekday(); if weekday == 6 or weekday == 7 : print('跳过周末'); return; # 初始化下载目录 saveDir = conf.get('saveDir') + '/' + str(targetDate.year) + str(targetDate.month).zfill(2) + '/'; if not path.exists(saveDir) : os.makedirs(saveDir, exist_ok = True); # 生成特定日期的提交数据 postData = parse.urlencode({'year': str(targetDate.year), 'mon': str(targetDate.month).zfill(2), 'day': str(targetDate.day)}).encode(conf.get('encoding')); # 请求特定日期的下载页面 page = request.urlopen(conf.get('indexUrl'), postData); pageStr = page.read().decode(conf.get('encoding')); start = 0 # 查找下载地址并开始下载 downIdx = findDownUrlIdx(pageStr, start); while downIdx != None : start = downIdx[0]; urlIdx = downIdx[1]; downIdx = findDownUrlIdx(pageStr, start); pdf = request.urlopen(conf.get('downUrl') + urlIdx); fileName = saveDir + '/' + str(targetDate.day).zfill(2) + '-' + urlIdx + '.pdf'; # 检查文件是否已经存在,并且大小相同 if path.exists(fileName) and path.getsize(fileName) == int(pdf.info().get('Accept-Length')) : print('跳过已经存在的相同大小的文件', fileName); continue; print('开始下载', urlIdx, '保存到', fileName); pdfFile = open(saveDir + '/' + str(targetDate.day).zfill(2) + '-' + urlIdx + '.pdf', 'bw'); pdfFile.write(pdf.read()); pdfFile.close(); # print(pdf.info());def findDownUrlIdx(source, start=0): ''' 从指定的源码中找到下载地址 @param source 页面源码 @param start 开始位置 默认为 0 @return 找到时返回 (结束位置, 下载地址URL ID)的tuple,找不到时返回 None ''' downStr = '<a href="./download.shtml?c='; idx = source.find(downStr, start); if idx >=0 : end = source.find('"', idx + len(downStr)); return end, source[idx + len(downStr) : end]; return None;def down(startDate = None, endDate = None): ''' @param startDate 开始日期(包括) @param endDate 结束日期(不包括) ''' conf = readConfig(); if(not login(conf)): print('login failed'); # 获取最后的下载日期,并开始下载最后下载日期到昨天的 chinadaily pdf saveDir = conf.get('saveDir'); if not path.exists(saveDir) : os.makedirs(saveDir, exist_ok = True); logFile = saveDir + '/lastdown'; # 默认下载日期为当月第一天 lastdate = date.today() - timedelta(date.today().day - 1); if path.exists(logFile) : # 已经下载过,读取最后的下载日期 log = open(logFile, 'a+'); log.seek(0); lastdateStr = str(log.read(10)); if len(lastdateStr) >= 10 : lastdate = datetime.strptime(lastdateStr, '%Y-%m-%d').date(); log.truncate(0); else: # 建立新的下载日志文件 log = open(logFile, 'w'); if startDate != None : lastdate = startDate; # 依次下载从最后下载日期到结束日期的chinadaily pdf 文件 try: while lastdate < date.today() if endDate == None else endDate: downADay(conf, lastdate); lastdate = lastdate + timedelta(1); finally: log.write(lastdate.strftime('%Y-%m-%d')); log.flush(); log.close();if __name__ == "__main__": import argparse; import sys; parser = argparse.ArgumentParser(description='下载chinadaily的PDF Paper'); parser.add_argument('-s', '--start', metavar='', help='开始日期(包括)'); parser.add_argument('-e', '--end', metavar='', help='结束日期(不包括),默认为今天'); args = parser.parse_args(); startDate = datetime.strptime(args.start, '%Y-%m-%d').date() if args.start != None else None; endDate = datetime.strptime(args.end, '%Y-%m-%d').date() if args.end != None else None; down(startDate, endDate);
程序的配置文件
[DEFAULT]loginUrl = http://pub1.chinadaily.com.cn/cdpdf/cndy/login.shtmlindexUrl = http://pub1.chinadaily.com.cn/cdpdf/cndy/index.shtmldownUrl = http://pub1.chinadaily.com.cn/cdpdf/cndy/download.shtml?c=encoding = utf-8loginPost = http://pub1.chinadaily.com.cn/cdpdf/cndy/login.shtml?do=loginsaveDir = d:/data/chinadailyusername = 这里更改为自己的用户名password = 这里更改为自己的密码
相关内容
- python将数据库的内容写入excel中,pythonexcel,[Python]代码
- python类的静态方法和类方法示例,python类静态示例,py
- django通过ajax发起请求返回JSON格式的数据,djangojson,这是
- python使用sched模块周期性抓取网页内容,pythonsched,使用
- python与计算物理:实现数值积分的Simpson方法,pythonsi
- python使用pyPdf裁切pdf文件,,This recipe
- python 批量加水印,python加水印,.py 放到 图片文件夹
- 使用compileall来预编译python代码,compileallpython,python中有
- python读取文件同时输出行号和内容,,file = open(
- Python实现二分查找(二分查询),python二分,本来想自己
评论关闭