ChatGPT免费站点 和 AIGC 工具导航
前一段写了一个AI工具导航,但是发现有些网站的favicon图标显示不出来(某外服务可显示,某内服务无法显示),于是就想办法解决这个问题。
favicon图标
导航网站制作上没什么技术难度,无非就是爬取一些网站的信息,然后列表展示出来。当然展示的时候,favicon图标是必不可少的,要不然就不好看了。
favicon图标是网站的标志,一般在浏览器的地址栏、标签页、书签栏等地方显示。一般是一个16×16, 32×32的小图标,通常存放在网站的根目录,图片格式是ico、png、svg等,名字常为favicon
、logo
等。
以下为favicon图标在HTML页面中声明:
1
|
<link rel="icon" href="https://www.baidu.com/favicon.ico" type="image/x-icon" />
|
**注意,**我们应直接使用rel="icon"
,现在很多网站依然使用rel="shortcut icon"
,这是一种过时的用法,可以被淘汰掉了。
favicon除了使用线上地址,还支持base64格式内联,例如:
1
|
<link rel="icon" href="data:image/x-icon;base64,AAABAA...8AAA==" type="image/x-icon" />
|
favicon图标显示方案
1. 使用 Favicon url
favicon图标不同于一般的图片素材,一般都不会有防盗链
的问题,所以我们可以直接使用线上地址。即:
1
|
<img src="https://www.baidu.com/favicon.ico" />
|
所以,你在获取网站信息的时候,记得获取favicon图标的url,直接使用即可。
2. 存储 favicon 图标
如果你不想使用线上地址,那么你可以将网站favicon图标存储到你的服务器上,自己做映射。这样做的好处是,你可以将favicon图标存储到你的CDN上,统一管理。缺点是,你需要自己维护这些图标,当然,你可以使用一些工具来自动化处理。
当然,你也可以存储为base64格式,这样就不需要额外的存储空间了,就是网站数据文件会变大。
3. 使用第三方服务
如果你不想自己存储favicon图标,那么你可以使用第三方服务,例如:Google Shared Stuff (S2)、faviconkit.com、icons.duckduckgo.com等。
Google Shared Stuff (S2)
Google Shared Stuff (S2) 提供了一个统一形式 URL api服务,该 URL 可以自动提取相应网站的图标图像并返回。
其使用方法为 https://www.google.com/s2/favicons?domain=abc.com&sz=24
,您需要将 abc.com 替换为实际网站的域名。
如:https://www.google.com/s2/favicons?domain=blog.mzh.ren&sz=24
,就会返回我博客的favicon图标,直接通过<img>
标签引用即可。
faviconkit.com
faviconkit.com api:invisible-scarlet-centipede.faviconkit.com/{website}/{size}
,替换 website
为实际网站的域名,size
为图标大小。
如:https://invisible-scarlet-centipede.faviconkit.com/blog.mzh.ren/24
,就会返回我博客的favicon图标。
通过以上免费服务,我们可以获取到网站的favicon图标,但是这些api都是外网的,如果你的网站是内网,那么就无法使用了。我到现在还没找到一个内网的api服务,如果你知道,欢迎告诉我。
favicon图标批量获取
我导航网站的数量大概有900个,如果手动获取,那就太麻烦了,所以我写了一个脚本来自动获取,这样就省了很多时间。
puppeteer
方式
Puppeteer | Puppeteer
Puppeteer is a Node.js library which provides a high-level API to control Chrome/Chromium over the DevTools Protocol. Puppeteer runs in headless mode by default, but can be configured to run in full (“headful”) Chrome/Chromium.
puppeteer
是一个用于浏览器自动化的 Node.js 库,它提供了一组用来操纵Chrome的API。
2017年,谷歌公开发布了 Puppeteer,由 Chrome DevTools 团队开发,使其比其他类似项目具有重大优势,因为它得到了世界上使用最广泛的浏览器的同一家公司的机构支持。
具体操作步骤如下:
- 首先通过head请求检查网站是否有favicon图标,如果有,那么直接使用,否则进入下一步。
2.通过puppeteer
打开网站,然后获取网站的favicon图标地址。
如果这两步都失败了,就使用自己的默认图标。
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
const http = require('http');
const https = require('https');
const fs = require('fs');
const puppeteer = require('puppeteer');
const { EventEmitter } = require('events')
EventEmitter.defaultMaxListeners = 20
const chatgptJson = require('./chatgpt.json');
const processFaviconUrl = async (item) => {
const url = item.url;
const url_object = new URL(url);
const website_url = url_object.protocol + "//" + url_object.host
const default_favicon_url = website_url + '/favicon.ico';
try {
console.log("check website url")
const website_url_available = await checkURLAvailable(website_url);
if (!website_url_available) {
console.log('website url not available');
return item;
}
} catch (err) {
console.log('Error:', err);
}
try {
console.log("check default favicon url")
const default_favicon_url_available = await checkURLAvailable(default_favicon_url);
console.log(`The URL is ${default_favicon_url_available ? 'valid' : 'invalid'}`);
if (default_favicon_url_available) {
console.log('has favicon');
item.favicon = default_favicon_url;
return item;
}
} catch (err) {
console.error('Error:', err);
}
try {
console.log('use puppeteer');
const browser = await puppeteer.launch({
headless: "new",
});
const page = await browser.newPage();
await page.setDefaultNavigationTimeout(0);
await page.goto(item.url);
// get favicon
const favicon = await page.evaluate(() => {
const favicon = document.querySelector('link[rel="icon"]') || document.querySelector('link[rel="shortcut icon"]');
return favicon ? favicon.href : null;
});
console.log(favicon);
if (favicon) {
item.favicon = favicon;
console.log(item);
}
await browser.close();
return item;
} catch (err) {
console.log(err);
}
}
function checkURLAvailable(url) {
return new Promise((resolve, reject) => {
const protocol = url.startsWith('https') ? https : http;
protocol
.request(url, { method: 'HEAD' }, (res) => {
if (res.statusCode >= 200 && res.statusCode < 400) {
resolve(true);
} else {
resolve(false);
}
})
.on('error', (err) => {
reject(err);
})
.end();
});
}
Promise.all(chatgptJson.map(processFaviconUrl)).then((results) => {
fs.writeFileSync('./chatgpt-new.json', JSON.stringify(results));
console.log('All done!');
}).catch((err) => {
console.error(err);
});
|
以上代码每次获取20-50个网站的favicon图标,多了就会卡死。我对异步和并发的一无所知,暂时没找到解决办法,哪位大佬发现了问题,欢迎指点一下,不胜感激。
playwright
方式
microsoft/playwright: Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
2020 年 1 月 31 日,微软发布Playwright。Playwright 在很多方面与 Puppeteer 非常相似。API 方法在大多数情况下是相同的,并且默认情况下 Playwright 还捆绑了兼容的浏览器。
Playwright 最大的区别在于跨浏览器支持。它可以驱动 Chromium、WebKit(Safari 的浏览器引擎)和 Firefox。
以下是使用playwright
获取favicon图标的代码:
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
|
const fs = require('fs');
const { chromium } = require('playwright');
(async () => {
const data = fs.readFileSync('chatgpt.json');
const websites = JSON.parse(data);
const browser = await chromium.launch();
const context = await browser.newContext();
for (let website of websites) {
const page = await context.newPage();
try {
await page.goto(website.url);
const faviconUrl = await page.$eval(
'link[rel="icon"]',
(el) => el.href
) || page.$eval('link[rel="shortcut icon"]', (el) => el.href);
console.log(`Favicon URL for ${website.url}: ${faviconUrl}`);
website.favicon = faviconUrl;
} catch (err) {
console.log(err);
continue;
}
await page.close();
}
fs.writeFileSync('chatgpt_new.json', JSON.stringify(websites));
await context.close();
await browser.close();
})();
|
代码运行后,会在当前目录下生成chatgpt_new.json
文件,里面包含了所有网站的favicon图标地址。
以上代码一次性获取了所有网站的favicon图标,感觉playwright
比puppeteer
强壮一些,访问不了也不会卡死。(纯属个人感觉)
以上两段代码都是在ChatGPT的帮助下完成的,至于原理,我也不太清楚,请路过的大佬指点一下。
代码库
mzhren/favicon: get sites favicon by playwright and puppeteer
含有两种方式获取favicon图标的代码,以及 chatgpt站点数据 chatgpt.json
和 aigc站点数据 aigc.json
, 欢迎大家star。
参考资料