最近在研读jdk源码,网上找了下资源,发现都不完整。

  后来新发现了一个有完整源码的地方,主要包括了java,c,c++的东西,装逼需要,就想拿来玩玩。但是,找了好多种下载打开的方式,发现都不对。于是,我随手写了python爬虫,把他搞定。

1. 思路分析

  1.1. 目标地址:http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/dddb1b026323/,打开后先自己看下,是否符合自己的需求;

  1.2. 分析此结构下主要有两种形式,一是目录文件,二是最终文件,特征明显,可区分出最终结果;

  1.3. 目录深度不确定,很自然地想到了递归;

  1.4. 查询有效目录,很自然地想到了正则表达式;

  1.5. 基于可能有中断的情况,可能需要进行断点下载,因此考虑加个简单的跳过功能;

1.6. 考虑到可能并发下载,为节省时间,应使用锁避免;

  1.7. 考虑可能出现重复下载某文件或目录的情况,耗费资源,因此加一个全局文件集,进行去重处理;

  1.8. 由于该文件目录很规律,就直接沿用其目录结构了;

  1.9. 考虑到本机环境可能不稳定,于是利用公司测试环境服务器;

  2.0. 开工!

2. 鲁棒的代码来一波

#!/usr/bin/python
# -*- coding: UTF-8 -*- import urllib,urllib2
import re
import os
import HTMLParser
dirbase = '/tmp'
urlbase = 'http://hg.openjdk.java.net'
url= urlbase + '/jdk8u/jdk8u/jdk/file/dddb1b026323/src' #/jdk,/hotspot
skip_to_p = ''
skip_find = False;
textmod ={'user':'admin','password':'admin'}
textmod = urllib.urlencode(textmod)
print(url)
req = urllib2.Request(url = '%s%s%s' % (url,'?',textmod))
res = urllib2.urlopen(req)
res = res.read()
alink = re.findall(r'<a',res)
allflist = [] table=re.findall(r'<tbody class="stripes2">(.+)<\/tbody>',res, re.S) harr = re.findall(r'href="(/jdk8u[\w\/\._]+)">(?!\[up\])', table[0]) def down_src_recursion(harr):
global allflist,skip_find;
if(not harr):
return False;
i=0; arrlen = len(harr)
lock_conflict_jump_max = 2; # 遇到文件锁时跳过n个文件,当前仍需跳过的文件数量
lock_conflict_jumping = 0;
print("in new dir cur...")
if(len(allflist) > 1500):
print('over 1500, cut to 50 exists...')
allflist = allflist[-800:]
for alink in harr:
i += 1;
alink = alink.rstrip('/')
if(skip_to_p and not skip_find):
if(alink != skip_to_p):
print('skip file, cause no find..., skip=%s,now=%s' % (skip_to_p, alink))
continue;
else:
skip_find = True;
if(alink in allflist):
print('目录已搜寻过:' + alink)
continue;
pa = dirbase + alink
if(os.path.isfile(pa)):
print('文件已存在,无需下载: ' + pa)
continue;
lockfile=pa+'.tmp'
if(os.path.isfile(lockfile)):
    lock_conflict_jumping = lock_conflict_jump_max;
print('文件正在下载中,跳过+%s...: %s' % (lock_conflict_jumping, lockfile))continue;
else:
if(lock_conflict_jumping > 0):
lock_conflict_jumping -= 1;
print('文件正在下载中,跳过+%s...: %s' % (lock_conflict_jumping, lockfile))continue;
# 首先根据后缀把下载中的标识标记好,因为网络下载时间更慢,等下载好后再加标识其实已为时已晚
if(pa.endswith(('.gif','.jpg','.png', '.xml', '.cfg', '.properties', '.make', '.sh', '.bat', '.html', '.c','.cpp', '.h', '.hpp', '.java', '.1'))):
os.mknod(lockfile);
reqt = urllib2.Request(urlbase + alink)
rest = urllib2.urlopen(reqt)
rest = rest.read()
allflist.append(alink)
if(rest.find('class="sourcefirst"') > 0):
print('这是个资源文件:%s %d/%d' % (alink, i, arrlen))
if(not os.path.isfile(lockfile)):
os.mknod(lockfile);
filename = alink.split('/')[-1]
linearr = re.findall(r'<span id=".+">(.+)</span>', rest)
fileObject = open(dirbase + alink, 'w')
for line in linearr:
try:
line = HTMLParser.HTMLParser().unescape(line)
except UnicodeDecodeError as e:
print('oops, ascii convert error accour:', e)
fileObject.write(line + '\r\n')
fileObject.close()
os.remove(lockfile);
else:
print('这是目录:%s %d/%d' % (alink, i, arrlen))
if(not os.path.exists(pa)):
print('创建目录:%s' % alink)
os.makedirs('/tmp' + alink, mode=0777)
ta=re.findall(r'<tbody class="stripes2">(.+)<\/tbody>',rest, re.S)
ha = re.findall(r'href="(/jdk8u[\w\/\._]+)">(?!\[up\])', ta[0])
down_src_recursion(ha) # go...
down_src_recursion(harr);

3. 让代码跑起来

python jdk-crawler.py

4. 瞅瞅下载得咋样了

du -sh /tmp/jdk8u/

ok, 以上,就打完了。等测试环境下载完成后,再通过ftp搬到你电脑上了。

随手用python写一个下载jdk源码爬虫的更多相关文章

  1. 一言不合就开始搞JDK源码

    ​Java是一门面向对象的编程语言,那什么是面向对象呢,下面将是历史上最通俗易懂的解释了,请看下图: 哈哈,解释的够清楚的了吧.闪. 从源码学编程的好处 学Java编程时,最好同时看一些Java的源码 ...

  2. [py]python写一个通讯录step by step V3.0

    python写一个通讯录step by step V3.0 参考: http://blog.51cto.com/lovelace/1631831 更新功能: 数据库进行数据存入和读取操作 字典配合函数 ...

  3. 【Python】如何基于Python写一个TCP反向连接后门

    首发安全客 如何基于Python写一个TCP反向连接后门 https://www.anquanke.com/post/id/92401 0x0 介绍 在Linux系统做未授权测试,我们须准备一个安全的 ...

  4. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  5. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装

    在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...

  6. 十行代码--用python写一个USB病毒 (知乎 DeepWeaver)

    昨天在上厕所的时候突发奇想,当你把usb插进去的时候,能不能自动执行usb上的程序.查了一下,发现只有windows上可以,具体的大家也可以搜索(搜索关键词usb autorun)到.但是,如果我想, ...

  7. Python写一个自动点餐程序

    Python写一个自动点餐程序 为什么要写这个 公司现在用meican作为点餐渠道,每天规定的时间是早7:00-9:40点餐,有时候我经常容易忘记,或者是在地铁/公交上没办法点餐,所以总是没饭吃,只有 ...

  8. 用python写一个自动化盲注脚本

    前言 当我们进行SQL注入攻击时,当发现无法进行union注入或者报错等注入,那么,就需要考虑盲注了,当我们进行盲注时,需要通过页面的反馈(布尔盲注)或者相应时间(时间盲注),来一个字符一个字符的进行 ...

  9. python写一个能变身电光耗子的贪吃蛇

    python写一个不同的贪吃蛇 写这篇文章是因为最近课太多,没有精力去挖洞,记录一下学习中的收获,python那么好玩就写一个大一没有完成的贪吃蛇(主要还是跟课程有关o(╥﹏╥)o,课太多好烦) 第一 ...

随机推荐

  1. angular如何引入公共JS

    一.现象 在项目的开发中,总会用到一些公司的脚本方法,同时,不希望在每个页面用到时又得需要引用,有点麻烦. 二.解决 1.在src文件夹下新建文件夹 utils: 2.在utils下新建文件 comm ...

  2. mysql执行计划id为空—UNION关键字

    简介 UNION 操作符用于合并两个或多个 SELECT 语句的结果集.例如,我有两个表,表1记录的是公司男员工的数据,包括年龄.姓名.职位.表2记录的是公司女员工的数据,包括姓名.家庭住址.手机号等 ...

  3. 1、背景介绍及移动云MAS平台 --短信平台

    目的: 刚开发完成一套短信平台以及一个Web端短信发送系统,短信平台耗时两个周.短信发送系统耗时两个多月,开发使用的技术没什么高科技含量,在此主要是记录下很多情况的处理方案,希望能让大家提出改善方案和 ...

  4. iOS.ObjC.__attribute__-directives

    __attribute__ Directives Reference 1. __attribute__ directives in Objective-C (AAAA+) (Read Again) h ...

  5. EasyPR源码剖析(3):车牌定位之颜色定位

    一.简介 对车牌颜色进行识别,可能大部分人首先想到的是RGB模型, 但是此处RGB模型有一定的局限性,譬如蓝色,其值是255,还需要另外两个分量都为0,不然很有可能你得到的值是白色.黄色更麻烦,它是由 ...

  6. python基础之Day22

    1.组合 什么是? 一个类的对象具备某一个属性,该属性值属于另一个类的对象,这样就可以引用 为何用: 解决类与类之间代码冗余问题 如何用? 2.菱形继承 单继承:一个个往父类上查找 菱形:一个子类继承 ...

  7. springmvd接收参数问题

    问题描述: 好久不写博客了,今天遇到一个问题,那就是post请求时,参数接收不到,当时我很纳闷,看代码: 就是这样几个参数,我使用postman请求时无法获取参数: 报错信息: "msg&q ...

  8. 为什么禁止在 foreach 循环里进行元素的 remove/add 操作

    首先看下边一个例子,展示了正确的做法和错误的错发: 这是为什么呢,具体原因下面进行详细说明: 1.foreach循环(Foreach loop)是计算机编程语言中的一种控制流程语句,通常用来循环遍历数 ...

  9. "tsc.exe"已退出,代码1

    公司开发新项目要用到ABP,于是到处在网上找些资料学习,在官网下好了模板(http://aspnetboilerplate.com/Templates),拿下来后用vs(博主用的是vs2013)编译后 ...

  10. Beta冲刺吐槽&&获小黄衫心得

    引 个人感觉本次Beta冲刺最大的槽点还是--反向延长 "冲刺周期" 做的不一样很容易,做的更好才是非常困难的 遗留的问题 经历了Alpha冲刺,组内大多数同学也大都对实践感到些许 ...