随手用python写一个下载jdk源码爬虫

news/2024/7/19 10:18:18 标签: 爬虫, java, c/c++

  最近在研读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搬到你电脑上了。

 

转载于:https://www.cnblogs.com/yougewe/p/9407243.html


http://www.niftyadmin.cn/n/1377131.html

相关文章

从编译器后门到 JS 后门

安全研究员 Travis Goodspeed 在 DEF CON 23 上报告了利用存在 bug 的 CLANG 编译器&#xff0c;在编译时间植入提权后门漏洞&#xff0c;创造一个人人能获得 root 权限的后门版 sudo。受此启发&#xff0c;Lets encrypt 项目的女工程师 Yan 发现&#xff0c;可以利用 JS 缩小器…

pytest 3.fixture介绍一 conftest.py

前言&#xff1a; 前面一篇pytest2 讲到用例加setup和teardown可以实现在测试用例之前或之后加入一些操作&#xff0c;但这种是整个脚本全局生效的&#xff0c;如果我想实现以下场景&#xff1a;  用例1需要先登录&#xff0c;用例2不需要登录&#xff0c;用例3需要先登录。很…

LeetCode 222. Count Complete Tree Nodes

由于是CBT&#xff0c;这道题一定是要用到CBT的性质&#xff0c;来减少时间复杂度。 由于是树的题&#xff0c;很容易想到递归&#xff0c;将原问题划归到子树上。完全二叉树除了最后一层一定是满的&#xff0c;因此子树中一定有一棵是满二叉树&#xff0c;而满二叉树的节点个数…

SQL Server中关于基数估计如何计算预估行数的一些探讨

SQL Server中关于基数估计如何计算预估行数的一些探讨 原文:SQL Server中关于基数估计如何计算预估行数的一些探讨关于SQL Server 2014中的基数估计&#xff0c;官方文档Optimizing Your Query Plans with the SQL Server 2014 Cardinality Estimator里有大量细节介绍&#xff…

python操作数据库-数据表

数据表&#xff1a; 数据类型&#xff1a; 帮助的三种形式&#xff1a; 在cmd中输入&#xff1a; help 要帮助的主题词&#xff0c;或 ? 要帮助的主题词 或 \h 要帮助的主题词 。 数据表的创建&#xff1a; CREATE database IF NOT exists zbltest2 default character set ut…

ftp-server(对象存储)

1、背景 在腾讯云弄了一个对象存储&#xff0c;想通过ftp上传照片 说明连接&#xff1a; 腾讯云&#xff1a;https://cloud.tencent.com/document/product/436/7214 GitHub&#xff1a;https://github.com/tencentyun/cos-ftp-server-V5 安装Pyhon2.7&#xff1a;https://cloud…

java.security.InvalidKeyException: Illegal key size aes解密失败

使用微信时定期提示&#xff1a;java.security.InvalidKeyException: Illegal key size和 com.qq.weixin.mp.aes.AesException: aes解密失败 at com.qq.weixin.mp.aes.WXBizMsgCrypt.decrypt(WXBizMsgCrypt.java:169) at com.qq.weixin.mp.aes.WXBizMsgCrypt.decryptMs…

渗透测试的WINDOWS NTFS技巧集合

译者&#xff1a;zzzhhh 这篇文章是来自SEC Consult Vulnerability Lab的ReneFreingruber (ReneFreingruber)&#xff0c;分享了过去几年从各种博客文章中收集的或者是他自己发现的文件系统技巧&#xff0c;这些技巧不可以直接被利用。但是它们会在特殊情况下间接地产生可以被攻…