以前研究过百度爬虫,大概知道他是通过互相关注去爬别人的收藏的资源,但是磁力链接的爬取还真是不太清楚,研究一下。然后我发现09年之前,最大的种子下载平台,海盗湾,其实用的是Tracker服务器,但是很明显的侵权,因为他提供的这样一个工具,可以是Tracker是bt种子下载的灵魂,但是现在不需要了,因为大部分BT下载用的都是DHT协议。
查了一下发现应该是跟这个dht爬虫有点关系。
查了一下相关的概念。
对等计算(Peer to Peer,简称p2p)可以简单的定义成通过直接交换来共享计算机资源和服务,而对等计算模型应用层形成的网络通常称为对等网络。相信大家都用过迅雷,就不多说了。
使用P2P技术的有比特币,海盗湾之类的。
DHT(Distributed Hash Table,分布式哈希表),DHT由节点组成,它存储peer的位置,是一种分布式存储方法。在不需要服务器的情况下,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个DHT网络的寻址和存储,其中BT客户端包含一个DHT节点,用来联系DHT中其他节点,从而得到peer的位置,进而通过BitTorrent协议下载。
简单来说DHT就是负责管理提供信息和服务节点的管理与路由功能,两个需要区分的概念:
“peer” 是在一个 TCP 端口上监听的客户端/服务器,它实现了 BitTorrent 协议。
“节点” 是在一个 UDP 端口上监听的客户端/服务器,它实现了** DHT(分布式哈希表) 协议**。
Kademlia是DHT网络的一种实现。在Kademlia网络中,距离是通过异或(XOR)计算的,结果为无符号整数。distance(A, B) = |A xor B|,值越小表示越近。
KRPC 是节点之间的交互协议,是由 bencode 编码组成的一个简单的 RPC 结构,他使用 UDP 报文发送。一个独立的请求包被发出去然后一个独立的包被回复。这个协议没有重发。它包含 3 种消息:请求,回复和错误。对DHT协议而言,这里有 4 种请求:
ping 检查一个节点是否有效
find_node 向一个节点发送查找节点的请求,在初始路由表或验证桶是否存活时使用
get_peers 向一个节点发送查找资源的请求
announce_peer 向一个节点发送自己已经开始下载某个资源的通知
一条KRPC消息由一个独立的字典组成,其中t和y关键字是每条信息都包含的
MagNet协议,也就是磁力链接。是一个通过sha1算法生成一个20字节长的字符串,P2P客户端使用磁力链接,下载资源的种子文件,然后根据种子文件下载资源。
因已有现成的脚本实现,只需要对相关协议有个大概了解就可以动手了。
嗯复制完感觉还是不太懂呢 算了 随缘吧
伪装成DHT节点加入DHT网络中收集信息,DHT中node(加入网络的时候随机生成)与infohash都是使用160bit的表示方式,也就是40位的16进制,意味着数量级有2^160,爬虫主要收集get_peer、announce_peer这两个请求的信息
get_peers与torrent文件的infohash有关,找到待查资源是否有peer。这时KPRC中的q=get_peers,其中包含节点id和info_hash两个参数,如果被请求的节点有对应info_hash的peers,将返回一个关键字values,如果无则返回关键字nodes,同时也返回一个token,token在annouce_peer中需要携带。
参数:
{"id" : "<querying nodes id>", "info_hash" : "<20-byte infohash of target torrent>"}
回复:
{"id" : "<queried nodes id>", "token" :"<opaque write token>", "values" : ["<peer 1 info string>", "<peer 2 info string>"]}
或者
{"id" : "<queried nodes id>", "token" :"<opaque write token>", "nodes" : "<compact node info>"}
这里过来的info_hash不一定是有真实存在的
这个请求用来表明发出announce_peer请求的节点,正在某个端口下载torrent文件。包含四个参数请求节点id、info_hash、整型端口port和tonken,收到请求的节点检查这个token,如果相同,则返回节点的IP和port等联系信息。爬虫中不能直接用announce_peer,否则很容易从上下文中判断是通报虚假资源而被禁掉。
参数:
{"id" : "<querying nodes id>", "implied_port": <0 or 1>, "info_hash" : "<20-byte infohash of target torrent>", "port" : <port number>, "token" : "<opaque token>"}
回复:
{"id" : "<queried nodes id>"}
这里过来的info_hash表明已经有在下载了,大部分是存在的,这里主要收集这个请求的信息info_hash、ip、port、name(name不一定有)
ping和find_node和报文案例看一下官方文档或文章后的参考翻译文章,文档已经写得很详细了;了解了这两个请求,基本解决信息收集的问题了。