[教程] Linux下使用aria2+loli.lu免费下载迅雷离线资源

loli.lu已关闭!
如需使用迅雷会员功能,请购买迅雷会员服务
如需在OSX,Linux环境下下载迅雷离线,请参阅ThunderLixianExporter

对于Linux用户,无论你用不用Windows,都不会不知道迅雷和迅雷离线。
面对国内这苦B的网络环境,用http,ftp太慢,bt,ed2k过期,想用迅雷,额。。没客户端。。渣一样的客户端,用浏览器下吧,下一半断了还不能多线程,用命令行又有cookie验证。。。

这篇教程旨在帮助大家打造一个方便的高速下载平台,下载工具采用多线程的aria2c,中转网站采用loli.lu(迅雷离线分享)的导出功能,方便地解决这个问题。

工具介绍

aria2

aria2c是一个跨平台开源,多线程,多协议支持的下载器。
支持包括HTTP/HTTPS, FTP, BitTorrent多种内容的下载,并且支持多来源,多线程,有丰富的前端可供选用。

loli.lu

是我在Martian支持下共同创建的一个迅雷离线下载分享的开源项目。旨在帮助Linux和MAC用户更好的适用迅雷离线的丰富资源。
通过这个项目的中转,你可以免费获得可供下载的迅雷离线地址,并且可以将地址分享给好友进行下载。

安装aria2

如果您的发行版带有包管理器,aria2很有可能已经包含在源中,直接安装即可。例如来自http://sourceforge.net/apps/trac/aria2/wiki/Download的安装说明:

Debian and Ubuntu

apt-get install aria2

Fedora

yum install aria2

Mandriva

urpmi aria2

Arch

pacman -S aria2

Gentoo

emerge aria2

OpenSUSE

Build Service http://download.opensuse.org/repositories/network:/utilities/

Lunar Linux

lin aria2

AgiliaLinux

mpkg-install aria2

FreeBSD

http://www.freebsd.org/cgi/cvsweb.cgi/ports/www/aria2/

Mac OS X

http://www.macports.org/

Fink

http://pdb.finkproject.org/pdb/package.php/aria2

Cygwin

http://sourceware.org/cygwin/packages/aria2/

如果您的发行版很不幸的不在上述发行版中,请前往http://sourceforge.net/projects/aria2/files/stable/尝试适用源码安装。

当您安装完成之后输入

aria2c -v

出现

aria2 version 1.13.0
Copyright (C) 2006, 2011 Tatsuhiro Tsujikawa

......

表明安装成功,注意,由于aria2在1.10后参数变化,而我们的Loli.lu导出的是新的参数设定,需要aria2的版本高于1.10

获取下载链接

访问:https://loli.lu/,点击右上角的登录,使用Google账户授权:
login

然后点击想要下载的资源,在弹出的浮动框中的批量下载中,点击aria2的链接:
get link

之后,浮动框中会输出这个资源的所有aria2的链接:

aria2c -c -x5 --out \[SumiSora\]\[C3\]\[01\]\[GB\]\[x264\_aac\]\[720p\]\(5393D704\)\.ass --header 'Cookie:gdriveid=4B281B37A54B63BF6F47BBF2A8A22675;' 'http://gdl.lixian.vip.xunlei.com/download?fid=umOXSXI/nn0XdbUzcpjfYhEs+g2K7wAAAAAAAFEZlKH8Vp3sMEiGuAwWb4ynfSaB∣=666&threshold;=150&tid;=F0991DB1D9D3D750F20EB62624DE99D4&srcid;=4&verno;=1&g;=511994A1FC569DEC304886B80C166F8CA77D2681&scn;=c8&i;=59B01E2CB9D2E7B1B5A83016DF97D4D445BAE247&t;=6&ui;=191942368&ti;=50569010689&s;=61322&m;=0&n;=01145C8D0C6F72615D3A72D7025B30315D3A76A6025B783236556E853E635D5B3753019402283533395275D36F34292E611242E45F00000000'
aria2c -c -x5 --out \[SumiSora\]\[C3\]\[01\]\[GB\]\[x264\_aac\]\[720p\]\(5393D704\)\.mkv --header 'Cookie:gdriveid=4B281B37A54B63BF6F47BBF2A8A22675;' 'http://gdl.lixian.vip.xunlei.com/download?fid=2QPCJq1fI2pyx9Nbr9XkGGw/NgK7SEMVAAAAAIc3sATS9kleYgkLISA6zY0DXbEj∣=666&threshold;=150&tid;=7568C4810EDDE63A3C2982ADE0BF4234&srcid;=4&verno;=1&g;=8737B004D2F6495E62090B21203ACD8D035DB123&scn;=c10&i;=59B01E2CB9D2E7B1B5A83016DF97D4D445BAE247&t;=6&ui;=191942368&ti;=50569010689&s;=356731067&m;=0&n;=01145C8D0C6F72615D3A72D7025B30315D3A76A6025B783236556E853E635D5B3753019402283533395275D36F34292E6D0A47E45F00000000'
......

现在开始下载吧,先新建一个目录,比如

mkdir -p '[澄空学园][C3-魔幻三次方-][01-12][GB][720p MKV][全]'
cd '[澄空学园][C3-魔幻三次方-][01-12][GB][720p MKV][全]'

然后粘贴入这些命令

 *** Download Progress Summary as of Tue Dec 20 22:10:06 2011 ***               
================================================================================
[#1 SIZE:8.7MiB/340.2MiB(2%) CN:5 SPD:170.6KiBs ETA:33m08s]
FILE: /home/binux/work/lixian.xunlei/[SumiSora][C3][01][GB][x264_aac][720p](5393D704).mkv
--------------------------------------------------------------------------------

[#1 SIZE:11.9MiB/340.2MiB(3%) CN:5 SPD:142.4KiBs ETA:39m20s]
    SIZE:文件大小,进度      CN:线程数 SPD:速度      ETA:剩余时间

对了,如果如果中间打断一个任务,只要在原来的目录下,再次执行下载命令就可以继续下载了。
如果一个任务的连接过多,也可以考虑建一个文件先保存起来,然后sh down.sh这样下载就好了。

添加资源

在登录后就可以在右上角找到添加资源的链接啦
bar
add task
当然了,如果觉得麻烦,也可以直接填写链接获得高速下载链接:
add task 2

对了,及时不是发布资源,获得的下载链接依旧可以分享给好友,只需要点击分享按钮,将链接复制给好友就可以了。
当然你也可以适用我们的一键分享功能:
share

===

如果有任何问题,欢迎留言,或+足兆叉虫
或者直接提交BUG:https://github.com/binux/lixian.xunlei/issues

迅雷离线脚本+flexget 将离线资源自动下载回本地

OUT OF DATA

这个也是一篇教程,上接 “让资源灌满你的离线空间吧 — 迅雷离线插件 for flexget“。需要的工具依旧是flexget和lixian.xunlei插件。

本文是应+平芜泫的需求,自动将迅雷离线里面的文件下载回vps,然后再从教育网用IPV6下回本地。前两步不再复述,参考前文的步骤即可,直接步骤3。先上配置文件:

feeds:
  some_name:
    from_xunlei_lixian:
      username: "<your username>"
      password: "<your password>"
      limit: 30
      fields:
        base_path: /home/me/downloads
    accept_all: true
    exec:
      auto_escape: yes
      on_output:
        for_accepted: mkdir -p {{ fields.base_path }}/{{ taskname }} && aria2c -c -x5 --out '{{ fields.base_path }}/{{ taskname }}/{{ title }}' --header '{{ cookie }}' '{{ url }}'

这又是一个yaml的配置文件,其中from_xunlei_lixian是input,accept_all是过滤器,而exec作为输出来进行下载。

from_xunlei_lixian中,limit限制一次取出多少条结果,fields可以将里面的参数传递到output中。
output中可以使用的字段包括

  • title         文件名

  • url           离线地址

  • cookie     下载所需要的cookie

  • taskname 所属的任务名(比如BT)

  • size         文件大小

  • format     文件格式(不准确)

  • fields       在上文中设置的那些东西

exec的文档在http://flexget.com/wiki/Plugins/exec,auto_escape可以escape掉文件名中的奇怪字符,on_output和for_accepted对每一个文件进行下载任务。

指令中:

 mkdir -p /

用于在base_path下创建一个以taskname命名的文件夹,这样BT这样多文件的时候就会下载到同一个目录下了。

aria2c -c -x5 –out ‘//迅雷离线脚本+flexget 将离线资源自动下载回本地‘ –header ‘‘ ‘‘

使用aria2c使用5个线程,将文件下载到本地。当然,也可以使用wget,这么写就可以了:

wget -c -O ‘ //迅雷离线脚本+flexget 将离线资源自动下载回本地‘ –header ‘‘ ‘‘

好了,现在运行flexget –test试试吧,flexget会输出将要执行的命令,但是并不会真正的执行,可以作为测试。

可能你的离线空间里面已经积累了大量已经下载回本地的文件,重新下一遍是没有意义的,对吧,来试试这个命令:

flexget –learn

这样可以跳过下载步骤,但是这些文件依旧会记录下来,再执行flexget的时候就只会下载之后添加的文件了。

让资源灌满你的离线空间吧 -- 迅雷离线插件 for flexget

OUT OF DATA

迅雷离线空间已经开放到1PB了,总是用不完,手头上那个100M的种子压缩包里面东西好多啊,把它塞满离线空间如何?

这个是一篇教程,适用于所有python环境,包括Linux, Windows, OSX, routers, NAS boxes,只要有python环境就可以。(不过搭建python环境并不是本文的内容,本文默认您已经有python了)

1、工具介绍

我们这次使用的主要是两个东西

flexget是一个能够从RSS,HTML页面,CSV文件,本地目录等等地方抓取资源,经过过滤,然后下载的一套框架。
flexget会自动监控追踪下载过的资源,保证不会被重复下载,后端可以调用各种BT,命令来处理这些资源。

flexget对于操作分为三种基本类型:

Inputs
Filters
Outputs

lixian.xunlei是我写得一个lixian.xunlei.com的python API封装,本身是为了挖迅雷墙角的,不过本着一物多用的原则,提供了一个flexget的插件,支持作为资源的output向迅雷推送资源,也可以作为input从迅雷取出资源。

2、环境准备

介绍完插件,那么就开始动手吧,既然需要工具,那么首先安装他们。这里以linux环境为例,不过都是python的工具,你应该能很容易在其他的环境找到对应的命令。

  1. 安装flexget
    直接从pypi中安装即可,依赖会自动解决

easy_install flexget

  1. 安装xunlei.lixian
    由于暂时还没有自动安装脚本,只能手动了。。。首先是依赖

easy_install requests
easy_install pyparsing
easy_install beautifulsoup

然后安装插件:

下载https://gist.github.com/gists/1476520/download,将文件解压到 ~/.flexget/plugins 文件文件夹中(若文件夹不存在,创建一个)
注意:解压出来带了一层gist********的目录,请将文件从那个目录中拷贝出来

3、配置

flexget的配置使用的是yaml,虽然没有听说过,不过其实还是很简单的。。

flexget的配置文件位于  ~/.flexget/config.yml (若不存在,创建一个即可)。
一个基本的配置是这样的:

feeds:
  Fate/Zero:
    rss: http://bt.ktxp.com/rss-search-Fate%2FZero+%E6%BE%84%E7%A9%BA%E5%AD%A6%E5%9B%AD+720p.xml
    accept_all: true
    xunlei_lixian:
      username: "<your username>"
      password: "<your password>"

flexget将多个不同的来源视为不同的feed,放在feeds下,Fate/Zero是它的名字

在前面我们说过,flexget有input, filter, output三种类型,在这个feed下面的配置中rss就是input, accept_all是filter, output是xunlei_lixian。

对于一个feed来说,input, filter, output这三个角色是必不可少的,但是使用的插件是可以变化的,通过不同的插件组合来达到各种各样的功能。
更多的input, filter, output和他们的参数可以去http://flexget.com/wiki/Plugins这里参看。

虽然这三者总是需要的,但是每次都写一次完全相同的accept_all和xunlei_lixian也是一件麻烦的事情,于是你可以这么写

presets:
  global:
    accept_all: true
    xunlei_lixian:
      username: "<your username>"
      password: "<your password>"

feeds:
  Fate/Zero:
    rss: http://bt.ktxp.com/rss-search-Fate%2FZero+%E6%BE%84%E7%A9%BA%E5%AD%A6%E5%9B%AD+720p.xml
  C3:
    rss: http://bt.ktxp.com/rss-search-%E9%9B%AA%E9%85%B7%E5%AD%97%E5%B9%95%E7%BB%84+C3+%E7%B9%81%E4%BD%93+RMVB.xml
  local_file:
    find:
      path: /home/me/incoming
      mask: '*.torrent'

用presets就可以把一些公共的配置放到一起了

需要注意的地方是,如果参数中带中文,或者有其他特殊支付,比如’*.torrent’,请用引号包起来。

你可能注意到了,本地文件也是可以作为input的,写法就是用find插件,像例子中那样。
不过,由于xunlei只接受种子,所有一定要记得过滤 ‘*.torrent’ 啊,不然我也不知道会怎么样。。

好了,就是这样了,该做的都完成了,现在我们运行flexget看看吧:

输入命令flexget看看吧
如果不放心,可以先使用命令: flexget –test 来试试结果是否正确。

如果没出什么问题的话,资源已经通通导入到你的离线空间了,慢慢下载回来吧,或者也可以参考我的下一篇教程:自动将离线空间的内容通通下回本地

除了这种用法,flexget也可以订阅资源到transmission中等其他软件中,配合RSS可以达到自动订阅新番的效果,具体参阅http://flexget.com/wiki/Plugins中对应的插件就可以了。

CSS实现文字中间截断效果的一种尝试

CSS属性

text-overflow: ellipsis;
-o-text-overflow: ellipsis;
white-space: nowrap;

能够实现文字溢出时截断,不过只能在文字结尾处。但是像文件名这样的文字,很有可能一组的前面都是相同的,只有最后的一部分是不同的。这时候需要进行文字的中部截断。

而一般实现文字中间截断都是使用:

1、按照字符个数在服务器端直接截断
这样做的缺陷是,文字并不是等宽的,很容易产生长短不一的情况。

2、用js获取文本的长度,不断删除中间的文字
虽然说这种方式最为可行,但是总是感觉不优雅。。而且爬虫爬取的时候没办法获得完整的内容

于是尝试用自己的办法来解决这个问题

首先这个是演示地址,和代码:http://jsbin.com/okopiz

考虑到浏览器默认支持的截断其实效果还不错,为了达到中部截断的效果,可以将文字分成前后两个部分。然后将前面部分的文字设置成溢出隐藏,而后面部分的文字接上即可。
在实际操作中,使用了padding这个属性,在div尾部推出200px的空间用于放置文字的结尾部分。

只需要保证后面文字不超出200px的空间即可。

不过,这里有个问题:
如果将后面文字固定在200px空间内的话,当宽度足够显示整个文字的时候,会导致后面部分文字被推开。
而如果不这么做的话,当文字溢出,会导致后面部分位置不正确。。

一直没有想到好的办法解决这个问题。。。于是只好求助于js了。。这个是一个缺憾吧。。

使用Valgrind检测内存泄漏

valgrind_介绍

Valgrind是一个GPL的软件,用于Linux(For x86, amd64 and ppc32)程序的内存调试和代码剖析。你可以在它的环境中运行你的程序来监视内存的使用情况,比如C 语言中的malloc和free或者 C++中的new和 delete。使用Valgrind的工具包,你可以自动的检测许多内存管理和线程的bug,避免花费太多的时间在bug寻找上,使得你的程序更加稳固。

valgrind的主要功能

Valgrind工具包包含多个工具,如Memcheck,Cachegrind,Helgrind, Callgrind,Massif。下面分别介绍个工具的作用:

Memcheck 工具主要检查下面的程序错误:

  • 未初始化的内存 (Use of uninitialised memory)

  • 已经释放了的内存 (Reading/writing memory after it has been free’d)

  • 超过 malloc分配的内存空间(Reading/writing off the end of malloc’d blocks)

  • 对堆栈的非法访问 (Reading/writing inappropriate areas on the stack)

  • 申请的空间是否有释放 (Memory leaks - where pointers to malloc’d blocks are lost forever)

  • malloc/free/new/delete申请和释放内存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])

  • src和dst的重叠(Overlapping src and dst pointers in memcpy() and related functions)

============= 我不是分割线 ===============

最近发现我们的爬虫的内存泄漏现象已经达到完全无法接受的地步,泄漏的内存将整个内存使用完之后,继续占用swap,直到整个系统无相应,负债超过了60。。直到swap再也没有空间,内核将爬虫的程序干掉了事。。

于是检查内存泄漏不得不立即执行,稍微google了一下,决定使用Valgrind

下载编译安装毫无压力,就不说了,毫无意义。

之后就是使用了。由于Valgrind能够直接对二进制的程序进行检测,完全不需要修改代码,连重新编译都不需要,所以直接上。

在这里犯了个错误,由于程序是通过启动脚本启动的,于是我就valgrind –tool=memcheck –leak-check=full 结果完全都是没有内存泄漏。。

在脚本里面程序是fork执行的,这样没法监控吧,于是这样:

valgrind --tool=memcheck --leak-check=full bin/crawler --bigtable_implementation=Mysql --mysql_host=localhost $*

OK,程序运行明显变慢了,过一段时间后CUT掉,输出好多。。于是

valgrind --tool=memcheck --leak-check=full bin/crawler --bigtable_implementation=Mysql --mysql_host=localhost $* 2>&1 | tee memcheck

得到如下的信息:

==18073== Memcheck, a memory error detector
==18073== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==18073== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==18073== Command: bin/crawler --bigtable_implementation=Mysql --mysql_host=localhost
==18073==
libprotobuf INFO srcs/mysql_table_client.cc:98] Database Selected.
libprotobuf INFO srcs/mysql_table_client.cc:103] Initialized successfully.
libprotobuf INFO srcs/mysql_table_client.cc:98] Database Selected.
libprotobuf INFO srcs/mysql_table_client.cc:103] Initialized successfully.
libprotobuf INFO srcs/crawl_queue.cc:48] loading processing tasks ...
libprotobuf INFO srcs/crawl_queue.cc:57] loading queue tasks ...
libprotobuf INFO srcs/crawl_queue.cc:66] loading delayed tasks ...
libprotobuf INFO srcs/crawl_queue.cc:74] loaded 16750 tasks ...
libprotobuf INFO srcs/crawl_queue.cc:77] initialize buckets ...
libprotobuf INFO srcs/redis_client.cc:78] RedisClient::Initialize...
libprotobuf INFO srcs/js_interpreter.cc:204] JavaScript-C 1.8.5 2011-03-31
libprotobuf INFO srcs/js_interpreter.cc:601] Setup runtime successfully.

................

==18073== 7,592 bytes in 785 blocks are definitely lost in loss record 1,498 of 1,615
==18073==    at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
==18073==    by 0x4FD59B2: js::VectorToIdArray(JSContext*, js::AutoIdVector&, JSIdArray**) (in /usr/local/lib/libmozjs185.so.1.0.0)
==18073==    by 0x4F4E262: JS_Enumerate (in /usr/local/lib/libmozjs185.so.1.0.0)
==18073==    by 0x4293D7: hypercrawler::JSInterpreter::GetObjectStringArrayProperty(JSObject*, std::string const&, std::map, std::allocat
or > >*) (js_interpreter.cc:361)
==18073==    by 0x429E96: hypercrawler::JSInterpreter::FinalizeReturnObject(unsigned long, hypercrawler::CallParserResponse*) (js_interpreter.cc:517)
==18073==    by 0x42AA59: hypercrawler::JSInterpreter::CallFunction(std::string const&, hypercrawler::CallParserRequest const&, hypercrawler::CallParserResponse*) (js_interpreter.cc:567)
==18073==    by 0x45974C: hypercrawler::ProcessCrawlRequest(hypercrawler::CrawlRequest&, hypercrawler::PuppetExecutionEngine&, std::string&, ypercrawler::CrawlResponse&, hyperindex::Document&, std::vector >&, std::string) (crawling_process_request.cc:170)
==18073==    by 0x446B06: hypercrawler::CrawlingWorker::operator()() (crawling_worker_service.cc:186)
==18073==    by 0x62C8D3F: thread_proxy (in /usr/lib/libboost_thread-mt.so.1.42.0)
==18073==    by 0x3546C0673C: start_thread (in /lib64/libpthread-2.5.so)
==18073==    by 0x35460D44BC: clone (in /lib64/libc-2.5.so)
==18073==
==18073==
==18073== LEAK SUMMARY:
==18073==    definitely lost: 90,928 bytes in 8,466 blocks
==18073==    indirectly lost: 0 bytes in 0 blocks
==18073==      possibly lost: 4,077,170 bytes in 38,041 blocks
==18073==    still reachable: 21,575,205 bytes in 70,837 blocks
==18073==         suppressed: 0 bytes in 0 blocks
==18073== Reachable blocks (those to which a pointer was found) are not shown.
==18073== To see them, rerun with: --leak-check=full --show-reachable=yes
==18073==
==18073== For counts of detected and suppressed errors, rerun with: -v
==18073== ERROR SUMMARY: 390 errors from 259 contexts (suppressed: 4 from 4)

definitely lost: 90,928 bytes in 8,466 blocks

这个就是表示存在内存泄漏,而因为是用的SpiderMonkey存在自己内存回收机制,并且是非正常退出,possibly lost暂时能够接受。

可以看出Valgrind,7,592 bytes in 785 blocks are definitely lost in loss record 1,498 of 1,615这一段的执行路径上存在内存泄漏。

通过查阅文档JS_EnumerateJS_EncodeString这两个SpiderMonkey API函数是需要用户释放内存的。。而我确实没有释放。。

我不得不吐槽。。JS_EncodeString的文档里面**The caller may modify it and is responsible for freeing it.**,就这么一句话说到要用户负责释放。。就不能写大一点吗!

明明上面一段还是说”The array returned by JS_GetStringBytes or JS_GetStringBytesZ is automatically freed when str is finalized by the JavaScript garbage collection mechanism.”来着。。

于是,正常释放之后,再次执行Valgrind检查没问题,OK,问题解决。

记一次神奇的BUG —— 慎用sqlalchemy的autocommit

东西是是用sqlalchemy写的数据处理的程序。就是从一个库里面取出数据,然后处理后写回去。

数据库用的是MySQL+MyISAM,因为考虑到MyISAM是不支持事务的,即使commit也没什么用,而且处理逻辑中对只是有一定可能对数据修改,还要commit太麻烦了。于是:

Session(autoflush=True, autocommit=True, expire_on_commit=True)

由于是周末,匆匆提交了就回去了。到了周六,我惊悚的看到pycounter做的数据统计非常完美地呈现出1/t的曲线

request rate

无论再次启动多次依旧如此。。。非常完美的1/t的曲线。。

=======================================================================

由于频率是成1/t,表示用时随着“处理过”的数据量以一次指数增长,想想最近添加的代码不太可能有这样增长的操作啊。

由于手头正好有pycounters在操作中打入几个计数器,观察到在sqlalchemy在做session.expire_all()的操作时符合O(x)的时间特性。

猜测是sqlalchemy的实例cache的机制导致每次处理完后,并没有释放掉获取到的对象,而expire_all对这些对象进行了一个大循环,以标记过期。
既然问题找到了,就好办了,不要使用sqlalchemy的autocommit,在修改后正常进行add,commit,故障消除。

随后查看了sqlalchemy的代码,expire_all的确是挨个expire操作的:

for state in self.identity_map.all_states():
    state.expire(state.dict, self.identity_map._modified)

而commit会将transaction close掉,清理掉identity_map,autocommit?还真没看出来怎么auto了。。

python 工具脚本: 线程池pool.py

这个脚本是仿照multiprocessing中的pool编写的(http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool)。

但是,python自带的multiprocessing的Pool是基于函数的,无法在线程内部保存各个线程的独立资源。例如在操作数据库时,数据库操作大都不是线程安全的,这时就需要每个线程有自己的连接。
其次,python自带的线程池在join之后会陷入内核态,无法接受CTRL+C,从而无法中断自行,这一点让我很是不爽。于是实现了这个线程池。

特性:
1、仿照multiprocessing的Pool,提供apply,apply_async,map,map_async这几个类似的接口,和wait函数进行等待执行结束

2、worker线程为一个类:

[crayon lang=”python]
class Work(threading.Thread):
def init(self):
pass
def do(self, args):
pass
[/crayon]

可以通过重载init来初始化一些线程自己的资源。重载do来自行需要的操作,参数会通过args传入。

3、wait时可以使用KeyboardInterrupt(CTRL+C)中断进程执行。

缺陷:线程没有返回值。。。

另:发现对于这种小东西gist真是方便。

源码:https://gist.github.com/992657

百度你能靠谱一点吗?

写个test_link的脚本,想要只获取http头部来测试链接是否失效。想着国内百度连接速度快些吧,于是用百度测试。。

assert(test_link(“http://baidu.com/xyz") == False)

结果。。百度返回的头居然是:

 Request URL:http://www.baidu.com/xyz
 Request Method:GET
 Status Code:302 Found
 Response Headers
 Cache-Control:max-age=86400
 Connection:Keep-Alive
 Content-Length:222
 Content-Type:text/html; charset=iso-8859-1
 Date:Mon, 28 Mar 2011 11:22:25 GMT
 Expires:Tue, 29 Mar 2011 11:22:25 GMT
 Location:http://www.baidu.com/search/error.html
 Server:Apache

好吧。。。302就302吧,我们看看后面的这个http://www.baidu.com/search/error.html是什么

 Request URL:http://www.baidu.com/search/error.html
 Request Method:GET
 Status Code:200 OK

喂喂,你这明显是error啊,200是怎么回事啊!明明页面上写着

您要访问的页面不存在

返回一个200到底是怎么回事啊!难道就不能返回个404让爬虫知道吗?
百度明明是个搜索引擎,写出来的网页就让自己认识是吗。。

google就明明白白地返回一个

 Request URL:http://www.google.com/xyz
 Request Method:GET
 Status Code:404 Not Found

类似的页面还有:

http://www.baidu.com/forbiddenip/forbidden.html

百度你还能再靠谱一点吗?

python工具脚本: 获取中文汉字拼音声母 getPY.py

一般来说要获取中文汉字全拼是需要查表的,不过只需要声母的话还是很简单就能实现的。

方法是利用GBK编码是按照拼音的顺序编排汉字的,所以,只需要将文字转化成GBK编码,通过匹配范围即可获得声母了(当然理论上也应该能获取全拼,我猜的-。-)。

这样的代码网上有很多,这里也是抄袭而来,抄自何处也忘记了。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/usr/bin/env python
# coding : utf-8
# author : binux([email protected])

def getFirstPY(word, encoding='utf-8'):
if isinstance(word, unicode):
try:
word = word[0].encode('gbk')
except:
return '?'
elif isinstance(word, str):
try:
word = word.decode(encoding)[0].encode('gbk')
except:
return '?'

if len(word) == 1:
return word
else:
asc = ord(word[0])*256 + ord(word[1]) - 65536
if asc >= -20319 and asc <= -20284:
return 'a'
if asc >= -20283 and asc <= -19776:
return 'b'
if asc >= -19775 and asc <= -19219:
return 'c'
if asc >= -19218 and asc <= -18711:
return 'd'
if asc >= -18710 and asc <= -18527:
return 'e'
if asc >= -18526 and asc <= -18240:
return 'f'
if asc >= -18239 and asc <= -17923:
return 'g'
if asc >= -17922 and asc <= -17418:
return 'h'
if asc >= -17417 and asc <= -16475:
return 'j'
if asc >= -16474 and asc <= -16213:
return 'k'
if asc >= -16212 and asc <= -15641:
return 'l'
if asc >= -15640 and asc <= -15166:
return 'm'
if asc >= -15165 and asc <= -14923:
return 'n'
if asc >= -14922 and asc <= -14915:
return 'o'
if asc >= -14914 and asc <= -14631:
return 'p'
if asc >= -14630 and asc <= -14150:
return 'q'
if asc >= -14149 and asc <= -14091:
return 'r'
if asc >= -14090 and asc <= -13119:
return 's'
if asc >= -13118 and asc <= -12839:
return 't'
if asc >= -12838 and asc <= -12557:
return 'w'
if asc >= -12556 and asc <= -11848:
return 'x'
if asc >= -11847 and asc <= -11056:
return 'y'
if asc >= -11055 and asc <= -10247:
return 'z'
return '?'

def getPY(string, encoding="utf-8"):
if isinstance(string, str):
string = string.decode(encoding)

result = []
for each in string:
result.append(getFirstPY(each))
return "".join(result)

最新的代码可以在https://github.com/binux/binux-tools/blob/master/python/getPY.py这里找到。

在windows环境中编译带python-dissector支持的wireshark(MSVC2010编译器)【无法开启】

虽然Windows的编程非常不爽,无论是编译环境还是编辑环境什么的,搭起来累的一比。不过,既然毕设题目是QQ协议分析,我总不能去分析Linux下那个阉割的QQ吧。
当然了,抓包之后扔到Linux下分析也是一个解决方案,不过实时的协议解析还是挺有吸引力的。

同时楼主一年来python上瘾,看着C++那几行开头include就头大,一直不想起手写C++,更何况Wireshark的API是C的。更可怕的是README.developer还没开始告诉你怎么写dissector呢,编程规范就一大堆,而且各种数据类型不建议使用,strlen不建议使用,strcp不建议使用。这不是从头又学一遍了嘛!

如果是这样还不如直接Lua搞起了, 最后顶着windows恶劣的编程环境尝试编译带python-dissector支持的wireshark。

step 1:
首先需要有一份源码。。建议直接到http://www.wireshark.org/下载最新稳定版的源码即可

step 2:
参照[Win32: Step-by-Step Guide] http://www.wireshark.org/docs/wsdg_html_chunked/ChSetupWin32.html 的过程编译即可。。完全没有压力

python-dissector:

在下不才,无法在windows平台下开启python-dissector支持。。

看了下代码,这部分代码还是相当的简单,基本上是处于测试,初步的阶段。
编译后执行若出现xxx地址不能为read之类的报错,将epan/wspython/wspy_register.c +128行

void register_all_py_protocols_func(register_cb cb _U_, gpointer client_data _U_)

函数修改为:

1
2
3
4
5
6
7
8
9
PyObject * py_reg;
// .....
/* load the python register module */
py_reg = PyFile_FromString(get_py_register_file(), "r");
if (py_reg == NULL) {
printf("no register file %sn", get_py_register_file());
return;
}
PyRun_SimpleFile(PyFile_AsFile(py_reg), get_py_register_file());

但是,一旦开启PYTHON_EMBED=1参数之后,会导致所有的plugin无法加载。。。

加上开发程度不高,文档几乎没有,暂时还是放弃了。。改用直接编写c plugin的方式吧

========================
PS:1.4.4中有函数原型变化,文档并没有更新:
如:
dissector_add_uint已经变为dissector_add