都在聚合,我也来写了个聚合搜索 —— 猫搜,给你更多想要的结果。

2020-01-07 20:38:13 +08:00
 hxx051

猫搜: https://www.moresearch.ga


你是否有过这种体验?遇到一个技术问题或一个关键词,一遍遍 google、baidu、知乎……、一遍遍输入、一遍遍搜索,以求获取最佳结果

太累,这两天实在受不了,就在想有没有一个网站,有个类似百度或谷歌的输入框,输入一次,把我们关心的各个搜索引擎的结果都展示出来呢?寻觅未果(找到的不是不能用就是不符合自己需要)

so,既然没有轮子,那就自己写一个吧

写这种聚合类型网站,首先想到的当然是爬虫啦,不过爬虫还得依赖服务器,手头没有(穷)怎么破?没关系,那我们就用纯前端的方式去做,互联网上有很多免费的空间。这里我们选择 coding.net 提供的免费 page 服务,可以放一些静态资源,当然你选择 github 也是可以的,不过速度相对会比较慢。而后我又去 Freenom 注册了一个免费域名:)

https://www.moresearch.ga/ 就叫「猫搜」,猫搜一下,给你更多结果。

万事俱备,只欠东风。接下来就是代码时刻啦~

先看下最终效果图:

噔!噔!噔!

对,就这么一个简单页面就可以满足我们需求了。别看它看似简单(刚开始我也是这么想的),后来我可是趟了很多坑。😓

1. 准备搜索引擎链接地址

类似 https://www.baidu.com/s?wd={query} 这种,使用{query}代表一个变量,即你要搜索的关键词,替换之后访问链接即可拿到搜索的结果。

这里我给大家准备了几个:

百度: http://www.baidu.com/s?wd={query}
谷歌: https://www.google.com/search?q={query}
必应: https://www.bing.com/search?q={query}
v2ex: https://www.google.com/search?q=site:v2ex.com/t {query}
知乎: https://www.zhihu.com/search?type=content&q={query}

2. 通过 iFrame 将各搜索结果聚合到一个页面

如刚才图示,我们想以这种界面结构去展示聚合结果,充分利用 PC 大屏的优势,提高效率

核心技术是用 iFrame,我也想当然会 so easy。。。可是测试下访问这是什么鬼?

emmm, 拒绝 iFrame 嵌套

遇到这种情况,不要试图挑战浏览器策略从前端破解 /微笑脸.jpg ,最好的方式是绕道而行:

  1. 和相关网站谈商务合作……我在说什么???好当我没说
  2. 通过 api 的方式去拿
  3. 代理
  4. 逼用户使用 IE6 ??

显然,上述方案只有第二条通过 api 去拿我们前端可以接受,而且纯前端还得是通过 ajax,拿到后在通过 iFrame 加载出来。

核心代码:

onSearch(inputText: string) {
    if (this.defineURL) {
      this.viewData.isLoading = true;
      this.viewData.isShowFrame = true;
      const url = this.defineURL.replace(`{query}`, inputText);
      this.urlGO = encodeURI(url);
      this.msService.httpClient.get(this.urlGO, {responseType: 'text'}) // get 请求 html
        .subscribe(value => {
          const iframe: any = document.getElementById(this.scrnIndexID);
          const iframedoc: any = iframe.contentDocument || iframe.contentWindow.document;
          iframedoc.children[0].innerHTML = value; // iFrame 加载 html
          let index = 0;
          let isFind = false;
          while (index < this.defineURL.length) {
            const number = this.defineURL.indexOf('/', index);
            if (number - 1 >= 0 && url.charAt(number - 1) !== ':' && url.charAt(number - 1) !== '/') {
              isFind = true;
              index = number;
              break;
            } else {
              index = number + 1;
            }
          }
          const htmlBaseElement = document.createElement('base');
          htmlBaseElement.href = isFind ? this.defineURL.substring(0, index + 1) : '/';
          htmlBaseElement.target = '_blank';
          iframedoc.children[0].children[0].appendChild(htmlBaseElement);// html 设置 base URL
          this.onLoad();
        }, error => {
          this.onLoad();
        });
      // this.viewData.url = this.ds.bypassSecurityTrustResourceUrl(this.urlGO);
    }
  }

3. 绕不过的坑:跨域

前端总有个绕不过的坑,那就是跨域。当我通过 api 去拿结果时,也掉到这个坑里:(

当然解决跨域有很多种方式:jsonp、iframe、代理 /反向代理、cors等等等等。可是没有后端配合,我们前端自己去搞,貌似就只能搭建代理服务器了,而且我又没有服务器……

终极大招

写到这,我已心灰意冷,手里没有服务器真的啥也干不了了吗?可惜了我写这么多代码...不行

作为自己使用,对付跨域还有个终极大招:禁止浏览器同源策略

以 Mac 下 chrome 为例:( windows 及其他浏览器可自行百度一下)

Mac: 

1.关闭浏览器
2.命令行下: 
open -a "Google Chrome" --args --disable-web-security  --user-data-dir

以上,我们又可以开心的搜索了:)

ps. 若有同学知道 源站限制 iFrame 嵌套,ajax 纯前端跨域的更好解决方案的,欢迎私信赐教,感谢🙏

更多原创尽在公众号: 「优雅的程序员呀」。程序员赚钱之道。优雅的技术,优雅的赚钱。

关注公众号,可以加我好友交流,也可加群技术交流哦。

2871 次点击
所在节点    程序员
26 条回复
hxx051
2020-01-08 09:09:29 +08:00
@dasenlin 大佬遇到拒绝 iframe 嵌套或跨域的问题了吗😂
hxx051
2020-01-08 09:10:05 +08:00
@Les1ie 嗯,有空买台服务器搞个代理😄
jiorix
2020-01-08 10:25:04 +08:00
地址访问不了了,是关掉了吗?
hxx051
2020-01-08 13:16:26 +08:00
@jiorix 用的免费空间,性能有限,可重新刷新试试😕
dasenlin
2020-01-08 15:15:30 +08:00
@hxx051 google 是拒绝 iframe 调用的
Duduchao
2020-01-16 16:13:35 +08:00
感觉兄弟写得这么细致。
不过,这种页面布局,个人感觉看起来有点累

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/635909

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX