日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
用TypeScript開發(fā)爬蟲程序

全局安裝typescript:

創(chuàng)新互聯(lián)成立10年來,這條路我們正越走越好,積累了技術(shù)與客戶資源,形成了良好的口碑。為客戶提供成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計、網(wǎng)站策劃、網(wǎng)頁設(shè)計、域名申請、網(wǎng)絡(luò)營銷、VI設(shè)計、網(wǎng)站改版、漏洞修補等服務(wù)。網(wǎng)站是否美觀、功能強大、用戶體驗好、性價比高、打開快等等,這些對于網(wǎng)站建設(shè)都非常重要,創(chuàng)新互聯(lián)通過對建站技術(shù)性的掌握、對創(chuàng)意設(shè)計的研究為客戶提供一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進步。

 
 
  1. npm install -g typescript

目前版本2.0.3,這個版本不再需要使用typings命令了。但是vscode捆綁的版本是1.8的,需要一些配置工作,看本文的處理辦法。

測試tsc命令:

 
 
  1. tsc

創(chuàng)建要寫的程序項目文件夾:

 
 
  1. mkdir test-typescript-spider

進入該文件夾:

 
 
  1. cd test-typescript-spider

初始化項目:

 
 
  1. npm init

安裝superagent和cheerio模塊:

 
 
  1. npm i --save superagent cheerio

安裝對應(yīng)的類型聲明模塊:

 
 
  1. npm i -s @types/superagent --save 
  2. npm i -s @types/cheerio --save 

安裝項目內(nèi)的typescript(必須走這一步):

 
 
  1. npm i --save typescript

用vscode打開項目文件夾。在該文件夾下創(chuàng)建tsconfig.json文件,并復(fù)制以下配置代碼進去:

 
 
  1. {
  2.     "compilerOptions": {
  3.         "target": "ES6",
  4.         "module": "commonjs",
  5.         "noEmitOnError": true,
  6.         "noImplicitAny": true,
  7.         "experimentalDecorators": true,
  8.         "sourceMap": false,
  9.      // "sourceRoot": "./",
  10.         "outDir": "./out"
  11.     },
  12.     "exclude": [
  13.         "node_modules"
  14.     ]

在vscode打開“文件”-“***項”-“工作區(qū)設(shè)置”在settings.json中加入(如果不做這個配置,vscode會在打開項目的時候提示選擇哪個版本的typescript):

 
 
  1. {
  2.    "typescript.tsdk": "node_modules/typescript/lib"

創(chuàng)建api.ts文件,復(fù)制以下代碼進去:

 
 
  1. import superagent = require('superagent');
  2. import cheerio = require('cheerio');
  3. export const remote_get = function(url: string) {
  4.     const promise = new Promise(function (resolve, reject) {
  5.         superagent.get(url)
  6.             .end(function (err, res) {
  7.                 if (!err) {
  8.                     resolve(res);
  9.                 } else {
  10.                     console.log(err)
  11.                     reject(err);
  12.                 }
  13.             });
  14.     });
  15.     return promise;

創(chuàng)建app.ts文件,書寫測試代碼:

 
 
  1. import api = require('./api');
  2. const go = async () => {
  3.     let res = await api.remote_get('http://www.baidu.com/');
  4.     console.log(res.text);
  5. }
  6. go(); 

執(zhí)行命令:

 
 
  1. tsc

然后:

 
 
  1. node out/app

觀察輸出是否正確。

現(xiàn)在嘗試抓取http://cnodejs.org/的***頁文章鏈接。

修改app.ts文件,代碼如下:

 
 
  1. import api = require('./api');
  2. import cheerio = require('cheerio');
  3. const go = async () => {
  4.     const res = await api.remote_get('http://cnodejs.org/');
  5.     const $ = cheerio.load(res.text);
  6.     let urls: string[] = [];
  7.     let titles: string[] = [];
  8.     $('.topic_title_wrapper').each((index, element) => {
  9.         titles.push($(element).find('.topic_title').first().text().trim());
  10.         urls.push('http://cnodejs.org/' + $(element).find('.topic_title').first().attr('href'));
  11.     })
  12.     console.log(titles, urls);
  13. }
  14. go(); 

觀察輸出,文章的標(biāo)題和鏈接都已獲取到了。

現(xiàn)在嘗試深入抓取文章內(nèi)容

 
 
  1. import api = require('./api');
  2. import cheerio = require('cheerio');
  3. const go = async () => {
  4.     const res = await api.remote_get('http://cnodejs.org/');
  5.     const $ = cheerio.load(res.text);
  6.     $('.topic_title_wrapper').each(async (index, element) => {
  7.         let url = ('http://cnodejs.org' + $(element).find('.topic_title').first().attr('href'));
  8.         const res_content = await api.remote_get(url);
  9.         const $_content = cheerio.load(res_content.text);
  10.         console.log($_content('.topic_content').first().text());
  11.     })
  12. }
  13. go(); 

可以發(fā)現(xiàn)因為訪問服務(wù)器太迅猛,導(dǎo)致出現(xiàn)很多次503錯誤。

解決:

添加helper.ts文件:

 
 
  1. export const wait_seconds = function (senconds: number) {
  2.     return new Promise(resolve => setTimeout(resolve, senconds * 1000));

修改api.ts文件為:

 
 
  1. import superagent = require('superagent');
  2. import cheerio = require('cheerio');
  3. export const get_index_urls = function () {
  4.     const res = await remote_get('http://cnodejs.org/');
  5.     const $ = cheerio.load(res.text);
  6.     let urls: string[] = [];
  7.     $('.topic_title_wrapper').each(async (index, element) => {
  8.         urls.push('http://cnodejs.org' + $(element).find('.topic_title').first().attr('href'));
  9.     });
  10.     return urls;
  11. }
  12. export const get_content = async function (url: string) {
  13.     const res = await remote_get(url);
  14.     const $ = cheerio.load(res.text);
  15.     return $('.topic_content').first().text();
  16. }
  17. export const remote_get = function (url: string) {
  18.     const promise = new Promise(function (resolve, reject) {
  19.         superagent.get(url)
  20.             .end(function (err, res) {
  21.                 if (!err) {
  22.                     resolve(res);
  23.                 } else {
  24.                     console.log(err)
  25.                     reject(err);
  26.                 }
  27.             });
  28.     });
  29.     return promise;
  30. }

修改app.ts文件為:

 
 
  1. import api = require('./api');
  2. import helper = require('./helper');
  3. import cheerio = require('cheerio');
  4. const go = async () => {
  5.     let urls = await api.get_index_urls();
  6.     for (let i = 0; i < urls.length; i++) {
  7.         await helper.wait_seconds(1);
  8.         let text = await api.get_content(urls[i]);
  9.         console.log(text);
  10.     }
  11. }
  12. go();

觀察輸出可以看到,程序?qū)崿F(xiàn)了隔一秒再請求下一個內(nèi)容頁。

現(xiàn)在嘗試把抓取到的東西存到數(shù)據(jù)庫中。安裝mongoose模塊:

 
 
  1. npm i mongoose --save
  2. npm i -s @types/mongoose --save 

然后建立Scheme。先創(chuàng)建models文件夾:

 
 
  1. mkdir models

在models文件夾下創(chuàng)建index.ts:

 
 
  1. import * as mongoose from 'mongoose';
  2. mongoose.connect('mongodb://127.0.0.1/cnodejs_data', {
  3.     server: { poolSize: 20 }
  4. }, function (err) {
  5.     if (err) {
  6.         process.exit(1);
  7.     }
  8. });
  9. // models
  10. export const Article = require('./article'); 

在models文件夾下創(chuàng)建IArticle.ts:

 
 
  1. interface IArticle {
  2.     title: String;
  3.     url: String;
  4.     text: String;
  5. }
  6. export = IArticle;

在models文件夾下創(chuàng)建Article.ts:

 
 
  1. import mongoose = require('mongoose');
  2. import IArticle = require('./IArticle');
  3. interface IArticleModel extends IArticle, mongoose.Document { }
  4. const ArticleSchema = new mongoose.Schema({
  5.     title: { type: String },
  6.     url: { type: String },
  7.     text: { type: String },
  8. });
  9. const Article = mongoose.model("Article", ArticleSchema);
  10. export = Article; 

修改api.ts為:

 
 
  1. import superagent = require('superagent');
  2. import cheerio = require('cheerio');
  3. import models = require('./models');
  4. const Article = models.Article;
  5. export const get_index_urls = async function () {
  6.     const res = await remote_get('http://cnodejs.org/');
  7.     const $ = cheerio.load(res.text);
  8.     let urls: string[] = [];
  9.     $('.topic_title_wrapper').each((index, element) => {
  10.         urls.push('http://cnodejs.org' + $(element).find('.topic_title').first().attr('href'));
  11.     });
  12.     return urls;
  13. }
  14. export const fetch_content = async function (url: string) {
  15.     const res = await remote_get(url);
  16.     const $ = cheerio.load(res.text);
  17.     let article = new Article();
  18.     article.text = $('.topic_content').first().text();
  19.     article.title = $('.topic_full_title').first().text().replace('置頂', '').replace('精華', '').trim();
  20.     article.url = url;
  21.     console.log('獲取成功:' + article.title);
  22.     article.save();
  23. }
  24. export const remote_get = function (url: string) {
  25.     return new Promise((resolve, reject) => {
  26.         superagent.get(url)
  27.             .end(function (err, res) {
  28.                 if (!err) {
  29.                     resolve(res);
  30.                 } else {
  31.                     reject(err);
  32.                 }
  33.             });
  34.     });

修改app.ts為:

 
 
  1. import api = require('./api');
  2. import helper = require('./helper');
  3. import cheerio = require('cheerio');
  4. (async () => {
  5.     try {
  6.         let urls = await api.get_index_urls();
  7.         for (let i = 0; i < urls.length; i++) {
  8.             await helper.wait_seconds(1);
  9.             await api.fetch_content(urls[i]);
  10.         }
  11.     } catch (err) {
  12.         console.log(err);
  13.     }
  14.     console.log('完畢!');
  15. })(); 

執(zhí)行

 
 
  1. tsc
  2. node out/app 

觀察輸出,并去數(shù)據(jù)庫檢查一下可以發(fā)現(xiàn)入庫成功了!

補充:remote_get方法的改進版,實現(xiàn)錯誤重試和加入代理服務(wù)器.放棄了superagent庫,用的request庫,僅供參考:

 
 
  1. //config.retries = 3;
  2. let current_retry = config.retries || 0;
  3. export const remote_get = async function (url: string, proxy?: string) {
  4.     //每次請求都先稍等一下
  5.     await wait_seconds(2);
  6.     if (!proxy) {
  7.         proxy = '';
  8.     }
  9.     const promise = new Promise(function (resolve, reject) {
  10.         console.log('get: ' + url + ',  using proxy: ' + proxy);
  11.         let options: request.CoreOptions = {
  12.             headers: {
  13.                 'Cookie': '',
  14.                 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',
  15.                 'Referer': 'https://www.baidu.com/'
  16.             },
  17.             encoding: 'utf-8',
  18.             method: 'GET',
  19.             proxy: proxy,
  20.             timeout: 3000,
  21.         }
  22.         request(url, options, async function (err, response, body) {
  23.             console.log('got:' + url);
  24.             if (!err) {
  25.                 body = body.toString();
  26.                 current_retry = config.retries || 0;
  27.                 console.log('bytes:' + body.length);
  28.                 resolve(body);
  29.             } else {
  30.                 console.log(err);
  31.                 if (current_retry <= 0) {
  32.                     current_retry = config.retries || 0;
  33.                     reject(err);
  34.                 } else {
  35.                     console.log('retry...(' + current_retry + ')')
  36.                     current_retry--;
  37.                     try {
  38.                         let body = await remote_get(url, proxy);
  39.                         resolve(body);
  40.                     } catch (e) {
  41.                         reject(e);
  42.                     }
  43.                 }
  44.             }
  45.         });
  46.     });
  47.     return promise;

另外,IArticle.ts和Article.ts合并為一個文件,可能更好,可以參考我另一個model的寫法:

 
 
  1. import mongoose = require('mongoose');
  2. interface IProxyModel {
  3.     uri: string;
  4.     ip: string;
  5.     port:string;
  6.     info:string;
  7. }
  8. export interface IProxy extends IProxyModel, mongoose.Document { }
  9. const ProxySchema = new mongoose.Schema({
  10.     uri: { type: String },//
  11.     ip: { type: String },//
  12.     port: { type: String },//
  13.     info: { type: String },//
  14. });
  15. export const Proxy = mongoose.model("Proxy", ProxySchema); 

導(dǎo)入的時候這么寫就行了:

 
 
  1. import { IProxy, Proxy } from './models';

其中Proxy可以用來做new、find、where之類的操作:

 
 
  1. let x = new Proxy();
  2. let xx = await Proxy.find({});
  3. let xxx = await Proxy.where('aaa',123).exec(); 

而IProxy用于實體對象的傳遞,例如

 
 
  1. function xxx(p:IProxy){

網(wǎng)站欄目:用TypeScript開發(fā)爬蟲程序
分享路徑:http://www.dlmjj.cn/article/dhddcsg.html