日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Node.js 种子下载器

發布時間:2023/12/18 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Node.js 种子下载器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Node.js 種子下載器

慶祝 2018 國慶,制作了一個 Node.js 的種子下載器。爬取頁面,根據頁面的鏈接,破解另外一個網站,下載種子文件。項目比較簡單,爬取頁面沒有使用任何爬蟲框架。項目源碼

Node.js 的安裝請看我的另外一篇文章,Node.js 的多版本安裝。

項目初始化

新建一個文件夾 FBIWarning,在該文件夾下打開命令行 CMD 或者 git bash。運行 npm init -y,該文件夾會生成一個 package.json 文件。

安裝依賴包

安裝依賴包 cnpm install --save cheerio iconv-lite request socks5-http-client。每個依賴包的功能如下:

  • cheerio // 解析 DOM
  • iconv-lite // 解決中文亂碼的問題
  • request // http 請求,圖片和種子的下載
  • socks5-http-client // socks 代理

爬取網頁策略

網頁之間,是靠鏈接聯系在一起的,符合數據結構里面的圖狀結構。所以,對應有如下兩種爬取策略。

  • 爬取所有列表頁面的鏈接后,再去爬取所有詳情頁面,對應圖算法的廣度優先遍歷。
  • 爬取一部分列表頁面,就去爬取詳情頁面。然后再去爬取列表頁面,爬取詳情頁面,循環進行,對應圖算法的深度優先遍歷。
  • 因為是國外網站,網絡可能隨時斷開,所以采用第二種策略比較好。同時,也能很快得到種子文件。為了防止重復爬取頁面,可以將爬取頁面的鏈接作為索引。

    請求代理

    網站是國外網站,需要使用梯子,否則不能爬取。代理傳送門。socks5-http-client 配合 reqeust 使用,可以解決代理的問題。但是,該代理只支持 socks 代理, http(s) 代理暫不支持。

    解決中文亂碼的問題

    目標網站的頁面編碼是 gbk ,而 request 依賴包的默認編碼是 UTF-8,使用默認編碼解碼方式,會導致頁面的中文變成亂碼。所以得到返回數據前,去掉默認編碼,就是設置編碼為 encoding: null,然后使用 iconv-lite 使用 gbk 方式解碼,這樣就可以解決中文編碼為亂碼的問題,代碼如下:

    const request = require("request") // 解析 dom const cheerio = require("cheerio") // 中文編碼 const iconv = require("iconv-lite") // 代理 const Agent = require("socks5-http-client/lib/Agent") const COMMON_CONFIG = require("./config") /*** 請求頁面* @param {String} requestUrl 請求頁面*/ function requestPage(requestUrl) {try {return new Promise((resolve, reject) => {if (!requestUrl) {resolve(false)}request.get({url: requestUrl,agentClass: Agent,agentOptions: {socksPort: 13838, // 代理端口socksHost: "127.0.0.1" // 代理 Host},headers: {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"},// 去掉默認 utf-8 解碼,否則解碼會亂碼encoding: null},function(err, response, body) {// 防止解析報錯try {// 統一解決中文亂碼的問題let content = iconv.decode(body, "gbk")let $ = cheerio.load(content)resolve($, err, response, body, content)} catch (error) {resolve(null)}})})} catch (error) {//如果連續發出多個請求,即使某個請求失敗,也不影響后面的其他請求Promise.resolve(null)} }

    并發請求

    分頁請求有很多個,可以使用遞歸來一個一個請求,但是寫法不太好看。所以,可以使用 ES7+ 里面的 async 函數,將同步過程變為異步過程。async 要配合 await 使用,就可以將同步過程變為異步過程。詳細了解 async 請看阮一峰 ES async

    async function innerRecursion() {for (let i = 1; i <= 100; i++) {let requestUrl = "http://www.baidu.com?page=" + i // 事例網站,非爬取網站let result = await this.requestPage(url)} }

    一個一個請求比較慢,可以使用 Promise.all 實現并發請求。當然,也可以使用 async 模塊 提高下載的并發量,有需要的可以自己去了解。這個 async 模塊并非上面的 async 函數。

    function innerRecursion() {let requestUrls = []for (let i = 1; i <= 100; i++) {let requestUrl = "http://www.baidu.com?page=" + i // 事例網站,非爬取網站requestUrls.push(requestUrl)}let promises = requestUrls.map(url => this.requestPage(url))Promise.all(promises).then(results => {// results 是一個數組,對應上面每個請求的結果}).catch(error => {// 捕獲請求中可能發生的錯誤console.log(error)}) }

    圖片下載

    圖片的下載非常簡單,代碼如下:

    /*** 下載文件* @param {String} url 請求鏈接* @param {String} filePath 文件路徑*/ function downloadFile(url, filePath) {// try...catch 防止一個請求出錯,導致程序終止 種子的下載相同try {if (!url || !filePath) {return false}request.get({url,agentClass: Agent,agentOptions: {socksPort: 13838, // 代理端口socksHost: "127.0.0.1" // 代理 Host},headers: {headers: {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"}}}).pipe(fs.createWriteStream(filePath))} catch (error) {console.log(error)} }

    破解網站種子下載

    解析詳情頁面,只能得到類似 http://www.jandown.com?ref=VENU794 的鏈接,需要破解該網站的種子下載。查看網站的種子下載方式,就是一個 post 請求,后端就會返回種子文件。剛開始的時候,不熟悉服務端的表單提交方式,導致文件一直得不到,后來詳細查看了 request 的官文文檔,發現是自己寫錯了。結合上面的圖片下載,種子的下載方式自然就有了,代碼如下:

    /*** 下載種子鏈接* @param {String} childDir // 子目錄* @param {String} downloadUrl // 下載種子地址*/ function downloadTorrent(childDir, downloadUrl) {try {// 解析出鏈接的 code 值let code = querystring.parse(downloadUrl.split("?").pop()).refif (!code || !childDir) {return false}// 發出 post 請求,然后接受文件即可request.post({url: "http://www.jandown.com/fetch.php",agentClass: Agent,agentOptions: {socksPort: 13838, // 代理端口socksHost: "127.0.0.1" // 代理 Host},headers: {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"},formData: {code}}).pipe(fs.createWriteStream(childDir + "/" + code + ".torrent"))} catch (error) {console.log(error)} }

    面向對象

    剛開始是使用面向過程的方式寫的,后來發現代碼太重復了,所以采用 OOP 改寫了整個代碼。詳細了解 javaScript Class 請看阮一峰 ES class

    總結

  • 學習中文編碼為亂碼的解決方法
  • 學習了 request 的代理以及文件下載功能
  • 破解種子網站的種子下載功能
  • js 面向對象開發
  • 爬蟲并發量解決
  • 感謝閱讀!

    轉載于:https://www.cnblogs.com/stevexu/p/9755337.html

    總結

    以上是生活随笔為你收集整理的Node.js 种子下载器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。