不同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的现象