├── .gitignore ├── LICENSE ├── README.md ├── main.go └── snapshot.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | dump.ktb 16 | torrent-spider -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 bttown 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # magnetlink spider 2 | a magnet-link spider in p2p. 3 | 一个磁力链接收集器,让你简单快速地收集DHT网络中其他节点下载资源的信息. 4 | 5 | 6 | 7 | #### Install && Usage 8 | go get -u github.com/bttown/torrent-spider 9 | go build github.com/bttown/torrent-spider 10 | ./torrent-spider 11 | 12 | #### Notice 13 | 1. 需要运行在公网服务器上, 否则收集到种子的可能性很小(正好形成UDP打洞) 14 | 2. 收集器刚启动的时候需要较长的时间(作者使用阿里云1核1G的机器测试大概需要1到2天:()来和DHT网络中的其他节点通信,当我们的节点被大量其他节点收录时,大量资源就会不请自来了 http://bttown.net/ 15 | 16 | ![snapshot](./snapshot.jpg) 17 | 18 | #### Code 19 | 20 | ```go 21 | package main 22 | 23 | import ( 24 | "fmt" 25 | "github.com/bttown/dht" 26 | "github.com/bttown/metadata" 27 | "log" 28 | ) 29 | 30 | var ( 31 | collectorQueriesBufferSize = 5000 32 | collectorMaxPendingQueries = 2000 33 | ) 34 | 35 | var ( 36 | // DHT 节点 37 | node = dht.NewNode(dht.OptionAddress("0.0.0.0:8662")) 38 | // 种子信息获取器 39 | collector = metadata.NewCollector(metadata.Options{ 40 | QueriesBufferSize: collectorQueriesBufferSize, 41 | MaxPendingQueries: collectorMaxPendingQueries, 42 | }) 43 | ) 44 | 45 | func main() { 46 | // 新获取种子时调用的Hook 47 | collector.OnFinish(func(req metadata.Request, torrent metadata.Torrent) { 48 | magnetLink := fmt.Sprintf("magnet:?xt=urn:btih:%s", req.HashInfo) 49 | log.Println("[Metadata]", magnetLink, torrent.Info.Name) 50 | }) 51 | defer collector.Close() 52 | 53 | // 当发现DHT网络中有人下载资源时,告知收集器去获取种子详细信息 54 | node.PeerHandler = func(ip string, port int, hashInfo, peerID string) { 55 | if err := collector.Get(&metadata.Request{ 56 | IP: ip, 57 | Port: port, 58 | HashInfo: hashInfo, 59 | PeerID: peerID, 60 | }); err != nil { 61 | panic(err) 62 | } 63 | 64 | } 65 | node.Serve() 66 | } 67 | 68 | ``` 69 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/bttown/dht" 6 | "github.com/bttown/metadata" 7 | "log" 8 | ) 9 | 10 | var ( 11 | collectorQueriesBufferSize = 5000 12 | collectorMaxPendingQueries = 2000 13 | ) 14 | 15 | var ( 16 | // DHT 节点 17 | node = dht.NewNode(dht.OptionAddress("0.0.0.0:8662")) 18 | // 种子信息获取器 19 | collector = metadata.NewCollector(metadata.Options{ 20 | QueriesBufferSize: collectorQueriesBufferSize, 21 | MaxPendingQueries: collectorMaxPendingQueries, 22 | }) 23 | ) 24 | 25 | func main() { 26 | collector.OnFinish(func(req metadata.Request, torrent metadata.Torrent) { 27 | magnetLink := fmt.Sprintf("magnet:?xt=urn:btih:%s", req.HashInfo) 28 | log.Println("[Metadata]", magnetLink, torrent.Info.Name) 29 | }) 30 | defer collector.Close() 31 | 32 | node.PeerHandler = func(ip string, port int, hashInfo, peerID string) { 33 | if err := collector.Get(&metadata.Request{ 34 | IP: ip, 35 | Port: port, 36 | HashInfo: hashInfo, 37 | PeerID: peerID, 38 | }); err != nil { 39 | panic(err) 40 | } 41 | 42 | } 43 | node.Serve() 44 | } 45 | -------------------------------------------------------------------------------- /snapshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bttown/torrent-spider/3c3665dbc65114e94d720e79ee908875f22ae7f5/snapshot.jpg --------------------------------------------------------------------------------