磁力鏈接
現(xiàn)在我們使用迅雷等工具下載資源的時候,基本上都只需要一個叫做磁力鏈接的東西就可以了,非常方便。
磁力鏈接是對等網(wǎng)絡(luò)中進行信息檢索和下載文檔的電腦程序。和基于“位置”連接的統(tǒng)一資源定位符不同,磁力鏈接是基于元數(shù)據(jù)文件內(nèi)容,屬于統(tǒng)一資源名稱。也就是說,磁力鏈接不基于文檔的 IP 地址或定位符,而是在分布式數(shù)據(jù)庫中,通過散列函數(shù)值來識別、搜索來下載文檔。因為不依賴一個處于啟動狀態(tài)的主機來下載文檔,所以特別適用沒有中心服務(wù)器的對等網(wǎng)絡(luò)。
磁力鏈接格式類似于 :
magnet:?xt=urn:btih:E7FC73D9E20697C6C440203F5884EF52F9E4BD28
分解一下這個鏈接
magnet:協(xié)議名。
xt:exact topic 的縮寫,表示資源定位點。BTIH(BitTorrent Info Hash)表示哈希方法名,這里還可以使用 SHA1 和 MD5。這個值是文件的標(biāo)識符,是不可缺少的。
一般來講,一個磁力鏈接只需要上面兩個參數(shù)即可找到唯一對應(yīng)的資源。也有其他的可選參數(shù)提供更加詳細的信息。
dn:display name 的縮寫,表示向用戶顯示的文件名。
tr:tracker 的縮寫,表示 tracker 服務(wù)器的地址。
kt: 關(guān)鍵字,更籠統(tǒng)的搜索,指定搜索關(guān)鍵字而不是特定文件。
mt:文件列表,鏈接到一個包含磁力鏈接的元文件 (MAGMA - MAGnet MAnifest)。
種子/DHT
通過磁力就可以獲取種子文件從而進行下載,這跟直接使用種子下載時一個道理的,只是少了從磁力到種子文件的一個過程而已。
BitTorrent 協(xié)議的種子文件可以保存一組文件的元數(shù)據(jù)。這種格式的文件被 BitTorrent 協(xié)議所定義。擴展名一般為“.torrent”。BitTorrent 使用”分布式哈希表”(DHT)來為無 tracker 的種子(torrents)存儲 peer 之間的聯(lián)系信息。這樣每個 peer 都成了 tracker。這個協(xié)議基于 Kademila 網(wǎng)絡(luò)并且在 UDP 上實現(xiàn)。
DHT 由節(jié)點組成,它存儲了 peer 的位置。BitTorrent 客戶端包含一個 DHT 節(jié)點,這個節(jié)點用來聯(lián)系 DHT 中其他節(jié)點,從而得到 peer 的位置,進而通過 BitTorrent 協(xié)議下載。
peer: 一個 TCP 端口上監(jiān)聽的客戶端/服務(wù)器,它實現(xiàn)了 BitTorrent 協(xié)議。
節(jié)點: 一個 UDP 端口上監(jiān)聽的客戶端/服務(wù)器,它實現(xiàn)了 DHT(分布式哈希表) 協(xié)議。 如果對 DHT 協(xié)議感興趣的話一定要看下 DHT 協(xié)議 的具體內(nèi)容,這里有 中文翻譯版本。(想要徹底讀懂項目的話一定要先了解該協(xié)議,代碼都是基于該協(xié)議實現(xiàn)的)
務(wù)實的實踐
項目來源
一般來講到 Python 爬取,大家的第一印象可能就是 requests/aiohttp,或者是 scrapy/pyspider 等爬蟲框架?;旧隙际菑闹付ǖ?HTML 頁面爬取信息。我有一個項目 torrent-cli(github.com/chenjiandongx/torrent-cli) 就是一個從資源網(wǎng)站上爬取磁力信息的工具。
然而我想自給自足獲取磁力種子,Google 了一番,發(fā)現(xiàn)大家基本上的代碼都是從 simDHT(github.com/fanpei91/simDHT)這個項目來的,首先這個項目很棒,但是有個問題就是代碼實現(xiàn)細節(jié)基本沒有一行注釋且不兼容 Python3。而很多網(wǎng)上同類的代碼基本上也是對這個照搬....
所以我知道我要開始干活了
經(jīng)過一波 happy coding 之后
項目結(jié)構(gòu)
核心代碼
crawler.py
從 DHT 網(wǎng)絡(luò)中獲取磁力鏈接。主要是利用一些大型的服務(wù)器 tracker,冒充 DHT 節(jié)點,使用 UDP 協(xié)議加入到 DHT 網(wǎng)絡(luò)中一波搜索以及和其他節(jié)點搞好關(guān)系,讓他們也分享我點資源。磁力數(shù)據(jù)存放在了 redis,利用 redis 的集合特性來去重。使用了多線程/多進程,用于提高爬取效率。在我的本地機器(i7-7700HQ/16G 內(nèi)存/8M 網(wǎng)速)跑了一下,效果還不錯,4 小時爬了 100 萬條磁力鏈接。
$ redis-cli
127.0.0.1:6379> scard magnets
(integer)1137627
然后代碼推送到我那臺性能強悍 1 核/2G 內(nèi)存/1M 網(wǎng)速阿里云服務(wù)器跑一下,哎....
magnettotorrent_aria2c.py 利用 aria2 將磁力鏈接轉(zhuǎn)換為種子文件。嘗試了一些其他的方式將磁力轉(zhuǎn)換為種子,但效果好像都不怎么理想。使用過 libtorrent 的 Python 版本,不知道是我打開方式不對還是它本來效率就不高,反正愣是一個種子都沒有轉(zhuǎn)換成功。
最后兜兜轉(zhuǎn)轉(zhuǎn)用到了 aria2 發(fā)現(xiàn)效率還可以。這里利用多線程跑一個命令。所以要先把 aria2 安裝到你的 PATH 中,具體參考官網(wǎng)介紹。
parse_torrent.py 解析種子文件內(nèi)容,同樣也是利用了 bencoder 進行解碼。有了種子我們當(dāng)然要看看到底是些什么資源了啦。你說世界就是這么小,在我解析出來的幾百個種子文件中,居然有幾個都是來自那個以2的10次方為標(biāo)志的社區(qū)。
有圖有真相
輔助代碼
database.py:封裝了關(guān)于 redis 的數(shù)據(jù)操作,主要是利用其集合數(shù)據(jù)結(jié)構(gòu)。
utils.py:一些工具函數(shù)
如何使用
獲取源碼及安裝依賴環(huán)境
$ git clone https://github.com/chenjiandongx/magnet-dht.git
$ cd magnet-dht
$ pip install -r requirements.txt# 確保已經(jīng)安裝好 redis,redis 的具體配置可以在 database.py 里面修改。
運行項目
至于進程數(shù)量可以在 crawler.py 進行調(diào)整$ python manage.py -h
usage: manage.py [-h][-s][-m][-p]
start manage.py with flag.
optional arguments:
-h,--help show this help message andexit-s run start_server func.
-m run magnet2torrent func
-p run parse_torrent func
深刻的感悟
自我學(xué)編程以來,我一直都是屬于興趣驅(qū)動的,對某種技術(shù)感興趣的話就會花時間去研究去嘗試。想成為一個有趣的人,去做一些有趣的事,真心覺得能把腦海里的想法轉(zhuǎn)變?yōu)榇a實現(xiàn)是件很棒的事,即使可能這件事在別人看來并沒有什么了不起。技術(shù)發(fā)展變化總是那么快,不緊跟著可能不小心就掉隊了。所以希望每個真心熱愛編程的人都能不忘初心,永遠保持對新技術(shù)的熱情,永遠能從編碼中找到樂趣。
-
服務(wù)器
+關(guān)注
關(guān)注
12文章
8958瀏覽量
85082 -
客戶端
+關(guān)注
關(guān)注
1文章
289瀏覽量
16640
原文標(biāo)題:用Python獲取磁力種子
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論