跳到主要内容

4 篇博文 含有标签「crawler」

查看所有标签

· 阅读需 2 分钟

在中国桌面操作系统,windows还是占主流,windows中文版使用的是GBK编码,然后我神奇的发现我所爬的那个网站,即使在linux下,返回的html竟然也是GBK编码的!!

javascript原生就支持几种编码转换,但是好像就两三种,种类特别少。一般情况下我们写javascript都是出于开发者环境,少遇到非Unicode的编码,所以考虑编码的情况并不多。但是万一遇到了咧?
那个时候,就该使用iconv-lite库了!

npm install iconv-lite

具体使用看教程就好,这里只提醒一下:使用iconv.decode(buffer, encoding)的时候,第一个参数传的是Buffer。做爬虫的时候,应该用http或者request直接拿出Buffer来,然后用iconv-lite转换。直接拿body估计是不行的。

var iconv = require('iconv-lite');
var getBufferWithHeader = co.wrap(function *(url) {
return new Promise(function (resolve) {
var buffer = [];
request({url, jar: jarWithCookie}, function (error, response, body) {})
.on('data', function (chunk) {
buffer.push(chunk);
})
.on('end', function () {
buffer = Buffer.concat(buffer);
resolve(buffer);
});
})
});
var getPageWithHeader = co.wrap(function *(url) {
var out = yield getBufferWithHeader(url);
return iconv.decode(out, 'GBK');
})

· 阅读需 1 分钟

我做爬虫的时候,遇到一个问题:我想把页面的标题作为文件夹名字,结果出错了,仔细一看,发现标题里含有字符/

使用windows的人应该都遇到过,给一个文件命名带有?的名字时,他就会告诉你有七八个字符是不能作为文件名的。
所以写一个函数把这些字符滤掉。

var makeFilenameValid = function (rawFilename) {
var InvalidCharRegex = /[\/:\*\?\"< >\|]/;
var okFilename = '';
_.each(rawFilename, function (char) {
var match = InvalidCharRegex.test(char);
if (!match){
okFilename += char;
}
});
return okFilename;
}

· 阅读需 1 分钟

正则匹配内容的多处地方的注意事项。

一般情况下,javascript的正则在匹配到第一个位置之后,就不在匹配了。然而在做爬虫的时候常常需要得到所有匹配的内容,这时可以用g修饰符来开启全局匹配。

var regex = /b/g;

var str = 'abba';

regex.test(str); // true
regex.test(str); // true
regex.test(str); // false

于是想获得所有符合的内容,可以通过:

var aFilePath = 'path to file';
var regex = /src=\"(pic\?id=\d{2,})\"/g;
var data = yield fs.readFileAsync(aFilePath);
var name = regex.exec(data)[1];
var urls = [];
var match;
picUrlRegex.lastIndex = 0;
do {
match = picUrlRegex.exec(data);
if(match)
urls.push(match[0]);
} while (match);

实现。
这里有一个特别需要主要的是,你需要手动的使用picUrlRegex.lastIndex = 0;来复位索引。

· 阅读需 3 分钟

这是关于如何在nodejs环境下,发起http请求时带上cookie的教程。

其实我用python写爬虫/发起http请求会熟手一些,不过nodejs作为一个能开发命令行程序的引擎,我又想多熟练js的编程,于是就试着用nodejs来做一个爬虫。
也是我对cookie的原理不熟悉吧,爬虫带cookie的时候,我试着在header上通过setHeader设置Cookie属性a=123; b=456这样子,但是服务器不认,也不知道是为什么。但是看到好像是说服务器可以设置不让本地读和写cookie,不知道是不是相关。

我设置header不行,但是人家可以啊!我使用的是:

npm install request

文档里有cookie的使用说明

request.cookie
Function that creates a new cookie.
request.cookie('key1=value1')

以及

var j = request.jar();
var cookie = request.cookie('key1=value1');
var url = 'http://www.google.com';
j.setCookie(cookie, url);
request({url: url, jar: j}, function () {
request('http://images.google.com')
})

看起来知道应该使用jar来组一个cookie然后扔给http请求使用就好了。
但在这里有一个要注意的坑在,就是 var cookie = request.cookie('key1=value1'); 一句,谁家的cookie只有一个property的啊!于是我就 var cookie = request.cookie('key1=value1; key2=value2'); ,然后服务器不认。
苦心孤诣地尝试很多遍之后,才挖掘出来应该是:

var cookie;
cookie = request.cookie('key1=value1');
j.setCookie(cookie, url);
cookie = request.cookie('key2=value2');
j.setCookie(cookie, url);

文档不能写清楚一点吗!

扔上代码,url是比较敏感的所以改成example了。

var collectionHost = 'www.example.com';
var collectionDomain = 'http://' + collectionHost;
var jarWithCookie = request.jar();
var cookieString = 'key1=value1; key2=value2; key3=value3; key4=value4; key5=value5';
for (kv of cookieString.split('; ')) {
jarWithCookie.setCookie(request.cookie(kv), collectionDomain);
}

var getBufferWithHeader = co.wrap(function *(url) {
return new Promise(function (resolve) {
var buffer = [];
request({url, jar: jarWithCookie}, function (error, response, body) {})
.on('data', function (chunk) {
buffer.push(chunk);
})
.on('end', function () {
buffer = Buffer.concat(buffer);
resolve(buffer);
});
})
});

其中,cookieString可以轻松从chrome的dev工具中搞出来。