不同site同步大量数据
Posted on 一 17 4月 2017 in python
一提到linux服务器同步数据,我能想到的就有curl
, wget
, rsync
, aria2c
这些命令。这两天我遇到一个问题,公司需要把深圳的一些项目数据同步到成都。深圳的数据是用apache的目录浏览模式,一个项目有多个文件夹,每个文件夹下又可能有多个文件和文件夹,需要把某个日期过后的所有文件同步到成都服务器。如果ssh可以直连深圳服务器的话,我就可以用rsync
来同步了,可问题就在于深圳服务器只开放了目录浏览模式。另外一个问题,我的电脑不能直接打开深圳的网址,需要配置公司的http代理。
思路: wget
下载文件
wget -q --show-progress -r -np -c -k -L -nH --reject *.html* -e http_proxy="http://192.168.2.1:2632" https://animorphsfanforum.com/fanart/2064/
-q: 安静模式,不输出,但是加上--show-progress就可以只显示下载进度
-r: 递归下载
-np: 就是no-parent的意思,不向父级遍历
-c: 断点续传
-nH: 不创建主机目录, 比如 http://abc.com/a/b/, 就不创建abc.com/a/b/这几个目录。这点很重要 -e command: 执行命令,我是设置了公司的http代理去访问目录网址
这种方式有几点不足:
- 不方便控制只选择哪个日期之后的文件夹下载。
- 重要的一点无法进行并发下载。我一个项目的数据有60多个文件,共10G大小。这样测试下载需要30分钟左右的速度。
- 本地上传到服务器也需要5分钟左右,这样就很浪费时间。
- 数据下载到本地很占硬盘空间。
思路2: aria2c
相对于上面,aria2c可以并发下载。但是它无法下载目录。最多可以下载批量的url,但这显然不是我想要的。
改进:python爬取链接,多进程,wget下载, 通过pipe ssh上传
-
通过
requests
库递归爬取链接。以[{'url':'http://aaa.zip', 'name':'aa.zip'},]的形式保存。requests也需要设置代理。proxies= { 'http':'http://192.168.2.1:2632' } r = requests.get(url, proxies=proxies)
-
使用multiprocess 和 pool库进行多进程下载
p = Pool(processes=8) # 也可以用p.map for j in xrange(len(files)): p.apply_async(single_download, args=(f['url'], new_dir)) p.close() p.join()
p.close() 不再往进程池里添加数据 p.join() 阻塞等待所有进程完成。 通过线程的方式,下载时间减少到了10分钟
-
wget 下载,pipe 上传
通过使用pipe技术,边下载边上传,不占用本地硬盘空间。
cmd = 'wget -q --show-progress -e http_proxy="http://192.168.2.1:2632" {} -O- | ssh {} \'[ -d {} ] && cat >> {} || mkdir -p {} && cat >> {}\''.format(url, cd_ssh_account, directory, full_path, directory, full_path)
注意到 wget下载后是ssh到服务器上,判断目录是否存在,否则就创建它,再写入到文件。注意这里是>>
而不是>
,否则会出现文件为0kb的现象