Heim Web-Frontend js-Tutorial Grundlegende Ideen zum Schreiben von Crawlern mit Node.js und Teilen von Beispielen für das Crawlen von Baidu images_node.js

Grundlegende Ideen zum Schreiben von Crawlern mit Node.js und Teilen von Beispielen für das Crawlen von Baidu images_node.js

May 16, 2016 pm 03:10 PM
javascript js node node.js 爬虫

其实写爬虫的思路十分简单:

  • 按照一定的规律发送 HTTP 请求获得页面 HTML 源码(必要时需要加上一定的 HTTP 头信息,比如 cookie 或 referer 之类)
  • 利用正则匹配或第三方模块解析 HTML 代码,提取有效数据
  • 将数据持久化到数据库中

但是真正写起这个爬虫来,我还是遇到了很多的问题(和自己的基础不扎实也有很大的关系,node.js 并没有怎么认真的学过)。主要还是 node.js 的异步和回调知识没有完全掌握,导致在写代码的过程中走了很多弯路。

模块化

模块化对于 node.js 程序是至关重要的,不能像原来写 PHP 那样所有的代码都扔到一个文件里(当然这只是我个人的恶习),所以一开始就要分析这个爬虫需要实现的功能,并大致的划分了三个模块。

主程序,调用爬虫模块和持久化模块实现完整的爬虫功能
爬虫模块,根据传来的数据发送请求,解析 HTML 并提取有用数据,返回一个对象
持久化模块,接受一个对象,将其中的内容储存到数据库中
模块化也带来了困扰了我一个下午的问题:模块之间的异步调用导致数据错误。其实我至今都不太明白问题到底出在哪儿,鉴于脚本语言不那么方便的调试功能,暂时还没有深入研究。

另外一点需要注意的是,模块化时尽量慎用全局对象来储存数据,因为可能你这个模块的一个功能还没有结束,这个全局变量已经被修改了。

Control Flow

这个东西很难翻译,直译叫控制流(吗)。众所周知,node.js 的核心思想就是异步,但是异步多了就会产生好几层嵌套,代码实在难看。这个时候,你需要借助一些 Control Flow 模块来重新整理你的逻辑。在这里就要推荐开发社区十分活跃,用起来也很顺手的 async.js(https://github.com/caolan/async/)。

async 提供了很多实用的方法,我在写爬虫时主要用到了

  • async.eachSeries(arr, fn, callback)  依次把 arr 中的每一个元素传给 fn,若 fn 回调没有返回错误对象就继续传下一个,否则把错误对象传给 callback,循环结束
  • async.parallel(fn[, fn] , callback)  当所有的 fn 都执行完成后执行 callback

这些控制流方法给爬虫的开发工作带来了很大的方便。考虑这么一个应用场景,你需要把若干条数据插入数据库(属于同一个学生),你需要在所有数据都插入完成后才能返回结果,那么如何保证所有的插入操作都结束了呢?只能是层层回调保证,如果用 async.parallel 就方便多了。

这里再多提一句,本来保证所有的插入都完成这个操作可以在 SQL 层实现,即 transaction,但是 node-mysql 截止我使用的时候还是没有很好的支持 transaction,所以只有自己手动用代码保证了。

解析 HTML

在解析过程中也遇到一些问题,这里一并记录下来。

最基本的发送 HTTP 请求获得 HTML 代码,使用 node 自带的 http.request 功能即可。如果是爬简单的内容,比如获得某个指定 id 元素中的内容(常见于抓去商品价格),那么正则足以完成任务。但是对于复杂的页面,尤其是数据项较多的页面,使用 DOM 会更加方便高效。

而 node.js 最好的 DOM 实现非 cheerio(https://github.com/MatthewMueller/cheerio) 莫属了。其实 cheerio 应该算是 jQuery 的一个针对 DOM 操作优化和精简的子集,包含了 DOM 操作的大部分内容,去除了其它不必要的内容。使用 cheerio 你就可以像用普通 jQuery 选择器那样选择你需要的内容。

下载图片
在爬数据时,我们可能还需要下载图片。其实下载图片的方式和普通的网页没有太大的区别,但是有一点让我吃了苦头。

注意下面代码中言辞激烈的注释,那就是我年轻时犯下的错误……

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

var req = http.request(options, function(res){

 

  //初始化数据!!!

  var binImage = '';

 

  res.setEncoding('binary');

  res.on('data', function(chunk){

   binImage += chunk;

  });

 

  res.on('end', function(){

 

   if (!binImage) {

    console.log('image data is null');

    return null;

   }

 

   fs.writeFile(imageFolder + filename, binImage, 'binary', function(err){

    if (err) {

     console.log('image writing error:' + err.message);

     return null;

    }

    else{

     console.log('image ' + filename + ' saved');

     return filename;

    }

   });

  });

 

  res.on('error', function(e){

   console.log('image downloading response error:' + e.message);

   return null;

  });

 });

 

 req.end();

Nach dem Login kopieren

GBK 转码
另外一个值得说明的问题就是 node.js 爬虫在爬 GBK 编码内容时转码的问题,其实这个问题很好解决,但是新手可能会绕弯路。这里就把源码全部奉上:

1

2

3

4

5

6

7

8

9

10

11

12

13

var req = http.request(options, function(res) {

  res.setEncoding('binary');

  res.on('data', function (chunk) {

  html += chunk;

  });

 

  res.on('end', function(){

  //转换编码

  html = iconv.decode(html, 'gbk');

  });

 });

 

 req.end();

Nach dem Login kopieren

这里我使用的转码库是 iconv-lite(https://github.com/ashtuchkin/iconv-lite),完美支持 GBK 和 GB2312 等双字节编码。

实例:爬虫批量下载百度图片

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

var fs = require('fs'),

 path = require('path'),

 util = require('util'), // 以上为Nodejs自带依赖包

 request = require('request'); // 需要npm install的包

  

// main函数,使用 node main执行即可

patchPreImg();

  

// 批量处理图片

function patchPreImg() {

 var tag1 = '摄影', tag2 = '国家地理',

  url = 'http://image.baidu.com/data/imgs?pn=%s&rn=60&p=channel&from=1&col=%s&tag=%s&sort=1&tag3=',

  url = util.format(url, 0, tag1, tag2),

  url = encodeURI(url),

  dir = 'D:/downloads/images/',

  dir = path.join(dir, tag1, tag2),

  dir = mkdirSync(dir);

  

 request(url, function(error, response, html) {

  var data = JSON.parse(html);

  if (data && Array.isArray(data.imgs)) {

   var imgs = data.imgs;

   imgs.forEach(function(img) {

    if (Object.getOwnPropertyNames(img).length > 0) {

     var desc = img.desc || ((img.owner && img.owner.userName) + img.column);

     desc += '(' + img.id + ')';

     var downloadUrl = img.downloadUrl || img.objUrl;

     downloadImg(downloadUrl, dir, desc);

    }

   });

  }

 });

}

  

// 循环创建目录

function mkdirSync(dir) {

 var parts = dir.split(path.sep);

 for (var i = 1; i <= parts.length; i++) {

  dir = path.join.apply(null, parts.slice(0, i));

  fs.existsSync(dir) || fs.mkdirSync(dir);

 }

 return dir;

}

  

var index = 1;

// 开始下载图片,并log统计日志

function downloadImg(url, dir, desc) {

 var fileType = 'jpg';

 if (url.match(/\.(\w+)$/)) fileType = RegExp.$1;

 desc += '.' + fileType;

 var options = {

  url: url,

  headers: {

   Host: 'f.hiphotos.baidu.com',

   Cookie: 'BAIDUID=810ACF57B5C38556045DFFA02C61A9F8:FG=1;'

  }

 };

 var startTime = new Date().getTime();

 request(options)

  .on('response', function() {

   var endTime = new Date().getTime();

   console.log('Downloading...%s.. %s, 耗时: %ss', index++, desc, (endTime - startTime) / 1000);

  })

  .pipe(fs.createWriteStream(path.join(dir, desc)));

}

Nach dem Login kopieren

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Empfohlen: Ausgezeichnetes JS-Open-Source-Projekt zur Gesichtserkennung und -erkennung Empfohlen: Ausgezeichnetes JS-Open-Source-Projekt zur Gesichtserkennung und -erkennung Apr 03, 2024 am 11:55 AM

Die Technologie zur Gesichtserkennung und -erkennung ist bereits eine relativ ausgereifte und weit verbreitete Technologie. Derzeit ist JS die am weitesten verbreitete Internetanwendungssprache. Die Implementierung der Gesichtserkennung und -erkennung im Web-Frontend hat im Vergleich zur Back-End-Gesichtserkennung Vor- und Nachteile. Zu den Vorteilen gehören die Reduzierung der Netzwerkinteraktion und die Echtzeiterkennung, was die Wartezeit des Benutzers erheblich verkürzt und das Benutzererlebnis verbessert. Die Nachteile sind: Es ist durch die Größe des Modells begrenzt und auch die Genauigkeit ist begrenzt. Wie implementiert man mit js die Gesichtserkennung im Web? Um die Gesichtserkennung im Web zu implementieren, müssen Sie mit verwandten Programmiersprachen und -technologien wie JavaScript, HTML, CSS, WebRTC usw. vertraut sein. Gleichzeitig müssen Sie auch relevante Technologien für Computer Vision und künstliche Intelligenz beherrschen. Dies ist aufgrund des Designs der Webseite erwähnenswert

PI -Knotenunterricht: Was ist ein PI -Knoten? Wie installiere und richte ich einen PI -Knoten ein? PI -Knotenunterricht: Was ist ein PI -Knoten? Wie installiere und richte ich einen PI -Knoten ein? Mar 05, 2025 pm 05:57 PM

Detaillierte Erläuterungs- und Installationshandbuch für Pinetwork -Knoten In diesem Artikel wird das Pinetwork -Ökosystem im Detail vorgestellt - PI -Knoten, eine Schlüsselrolle im Pinetwork -Ökosystem und vollständige Schritte für die Installation und Konfiguration. Nach dem Start des Pinetwork -Blockchain -Testnetzes sind PI -Knoten zu einem wichtigen Bestandteil vieler Pioniere geworden, die aktiv an den Tests teilnehmen und sich auf die bevorstehende Hauptnetzwerkveröffentlichung vorbereiten. Wenn Sie Pinetwork noch nicht kennen, wenden Sie sich bitte an was Picoin ist? Was ist der Preis für die Auflistung? PI -Nutzung, Bergbau und Sicherheitsanalyse. Was ist Pinetwork? Das Pinetwork -Projekt begann 2019 und besitzt seine exklusive Kryptowährung PI -Münze. Das Projekt zielt darauf ab, eine zu erstellen, an der jeder teilnehmen kann

PHP- und JS-Entwicklungstipps: Beherrschen Sie die Methode zum Zeichnen von Aktienkerzendiagrammen PHP- und JS-Entwicklungstipps: Beherrschen Sie die Methode zum Zeichnen von Aktienkerzendiagrammen Dec 18, 2023 pm 03:39 PM

Mit der rasanten Entwicklung der Internetfinanzierung sind Aktieninvestitionen für immer mehr Menschen zur Wahl geworden. Im Aktienhandel sind Kerzendiagramme eine häufig verwendete Methode der technischen Analyse. Sie können den sich ändernden Trend der Aktienkurse anzeigen und Anlegern helfen, genauere Entscheidungen zu treffen. In diesem Artikel werden die Entwicklungskompetenzen von PHP und JS vorgestellt, der Leser wird zum Verständnis des Zeichnens von Aktienkerzendiagrammen geführt und es werden spezifische Codebeispiele bereitgestellt. 1. Aktien-Kerzendiagramme verstehen Bevor wir uns mit dem Zeichnen von Aktien-Kerzendiagrammen befassen, müssen wir zunächst verstehen, was ein Kerzendiagramm ist. Candlestick-Charts wurden von den Japanern entwickelt

Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Jan 05, 2024 pm 06:08 PM

JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

Die Beziehung zwischen js und vue Die Beziehung zwischen js und vue Mar 11, 2024 pm 05:21 PM

Die Beziehung zwischen js und vue: 1. JS als Eckpfeiler der Webentwicklung; 2. Der Aufstieg von Vue.js als Front-End-Framework; 3. Die komplementäre Beziehung zwischen JS und Vue; Vue.

Effiziente Java-Crawler-Praxis: Weitergabe von Webdaten-Crawling-Techniken Effiziente Java-Crawler-Praxis: Weitergabe von Webdaten-Crawling-Techniken Jan 09, 2024 pm 12:29 PM

Java-Crawler-Praxis: So crawlen Sie Webseitendaten effizient Einführung: Mit der rasanten Entwicklung des Internets werden große Mengen wertvoller Daten auf verschiedenen Webseiten gespeichert. Um diese Daten zu erhalten, ist es oft notwendig, manuell auf jede Webseite zuzugreifen und die Informationen einzeln zu extrahieren, was zweifellos eine mühsame und zeitaufwändige Aufgabe ist. Um dieses Problem zu lösen, wurden verschiedene Crawler-Tools entwickelt, von denen der Java-Crawler eines der am häufigsten verwendeten ist. Dieser Artikel führt den Leser dazu, zu verstehen, wie man mit Java einen effizienten Webcrawler schreibt, und demonstriert die Praxis anhand spezifischer Codebeispiele. 1. Die Basis des Reptils

So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript Jan 05, 2024 pm 01:37 PM

Einführung in die Methode zum Abrufen des HTTP-Statuscodes in JavaScript: Bei der Front-End-Entwicklung müssen wir uns häufig mit der Interaktion mit der Back-End-Schnittstelle befassen, und der HTTP-Statuscode ist ein sehr wichtiger Teil davon. Das Verstehen und Abrufen von HTTP-Statuscodes hilft uns, die von der Schnittstelle zurückgegebenen Daten besser zu verarbeiten. In diesem Artikel wird erläutert, wie Sie mithilfe von JavaScript HTTP-Statuscodes erhalten, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist ein HTTP-Statuscode? HTTP-Statuscode bedeutet, dass der Dienst den Dienst anfordert, wenn er eine Anfrage an den Server initiiert

Beginnen Sie Ihre Java-Crawler-Reise: Erlernen Sie praktische Fähigkeiten zum schnellen Crawlen von Webdaten Beginnen Sie Ihre Java-Crawler-Reise: Erlernen Sie praktische Fähigkeiten zum schnellen Crawlen von Webdaten Jan 09, 2024 pm 01:58 PM

Austausch praktischer Fähigkeiten: Lernen Sie schnell, wie man Webseitendaten mit Java-Crawlern crawlt. Einführung: Im heutigen Informationszeitalter verarbeiten wir täglich große Mengen an Webseitendaten, und viele der Daten sind möglicherweise genau das, was wir brauchen. Um diese Daten schnell zu erhalten, ist das Erlernen des Umgangs mit der Crawler-Technologie zu einer notwendigen Fähigkeit geworden. In diesem Artikel wird eine Methode zum schnellen Erlernen des Crawlens von Webseitendaten mit einem Java-Crawler vorgestellt und spezifische Codebeispiele angehängt, damit der Leser diese praktische Fähigkeit schnell erlernen kann. 1. Vorbereitungsarbeiten Bevor wir mit dem Schreiben eines Crawlers beginnen, müssen wir Folgendes vorbereiten

See all articles