因为 GF 经常找我帮忙把某个微信号发的谋篇文章中的图片提取出来用,所以才写这样的一个工具。
之前我的做法是用 Chrome 打开要提取图片的页面,用 jquery-injection 这个浏览器插件插入一个 jquery 库,把所有 img 都提取出来,并只要 data-src 中的 url ,因为当你打开时服务端会根据你的设备给出最好的图片格式,例如 ios 就给原始的 gif , jpg 等, chrome 等会给出 webp 格式的,而 data-src 中的是原始文件 url 。
得到一个一行行的 url 后复制到编辑器中,替换\n 为',',这样就可以构造一个 python 中列表的样式,直接复制到 python 中处理,当然现在我可能会用 awk ,那样更快,不过得查一些函数。到 python 中主要是给 url 加 index ,例如 url 基本都是 HOST:/mmbiz/HASH/0?wx_fmt=gif 这样的格式,我会把 /0 替换成 /0.0 ,/0.1 ,/0.2 ,并把扩展名加好,扩展名来自 url 中的 wx_fmt 参数(现在看可能从 data-type 中取比较好), index 根据列表的 index 来,之后再把处理好的 url 复制到编辑器中保存,最后用 wget 下载,大约是:
for i in `cat urls`;do wget $i;done
前面加的 index 在这里就用得上了,下载好之后会按照顺序排好。
因为最近在搞 js 方面的东西,就用 nodejs 完成上面的工作,大约是这样:
var request = require('request');
var _ = require('lodash');
var url;
if (process.argv.length > 2) {
url = process.argv[2];
} else {
console.error('please provide url');
process.exit(1);
}
request.get({
url: url
}, function(err, response, body) {
if (response.statusCode != 200) {
console.log(err);
console.log(body);
} else {
var imgUrlPattern = /( http:\/\/mmbiz\.qpic\.cn\/mmbiz\/.*?(\?wx_fmt=(.*?))?)"/g;
var result;
var urls = [];
while((result = imgUrlPattern.exec(body)) != null) {
urls.push(result[1]);
}
urls = _.map(urls, function(url, index) {
return url.replace('/0', '/0.' + index);
});
_.forEach(urls, function(url) {
console.log(url);
});
}
});
之后可能会结合 express , kue , redis 等做一个和之前发布的提取微博视频似的那样的工具。
希望你们的 GF 找你们时也用得上。
修改了一下昨晚贴出的代码(因为长度超了所以不再贴出,只是多输出了 biz 参数)
下载部分的代码大概这样:
var fs = require('fs');
var mkdirp = require('mkdirp');
var request = require('request');
var _ = require('lodash');
var urls;
var lines;
var data = '';
var biz;
var SUPPORT_EXTS = {
'image/gif': 'gif',
'image/png': 'png',
'image/jpeg': 'jpg',
'image/jpg': 'jpg'
};
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function() {
var chunk = process.stdin.read();
if (chunk !== null) {
data += chunk;
}
});
process.stdin.on('end', function() {
lines = data.split('\n');
if (lines.length <= 1) {
console.log('no image list');
process.exit(1)
}
biz = lines[0];
urls = _.filter(lines, function(url, index) {
return index > 0 && !_.isEmpty(_.trim(url));
});
if (_.isEmpty(urls)) {
console.log('no image list');
process.exit(1);
}
mkdirp('data/' + biz, function(err) {
if (err) {
console.log(err);
} else {
_.forEach(urls, function(url, index) {
request.head({
url: url
}, function(err, response, body) {
if (err) {
console.log(err);
} else {
var contentType = response.headers['content-type'];
if (contentType == 'text/plain') {
return;
}
var ext = SUPPORT_EXTS[contentType];
if (!ext) {
console.log(contentType);
console.log(url);
}
var stream = fs.createWriteStream('data/' + biz + '/' + index + '.' + ext);
request.get(url).pipe(stream);
}
});
});
}
});
});
保存路径中使用 biz 的内容其实不太好, biz 的内容是 base64 编码后的 id ,可能是公众号 id ,这里作为一级目录显然可能会在提取同一个号的多篇文章时冲突,可以考虑添加其他几个参数作为目录的名字或者自己想办法保证
目前可以这样用:node cli.js URL | node download.js
,会在当前目录中创建 data 目录并保存图片到data/公众号 id
中
微信公众号文章中必须有的参数是:
1
sdsnyx 2015-12-13 23:59:01 +08:00 via iPhone
求一个这样的有好图片的公众号
|
2
yanwen 2015-12-14 00:05:01 +08:00
可以做成一个小工具不?
|
6
dawncold OP @chanssl 用命令行不是也可以吗,比如: for i in `node cli.js <URL>`;do wget $i;done
|
7
joshz 2015-12-17 12:04:19 +08:00
写成油猴脚本用户体验更好吧,不用复制粘贴了,设置个默认下载路径,看到微信公众号文章就提取。当然工作要复杂很多,我就放个嘴炮。
|