修改Google新闻以消除不需要的新闻来源

RSW*_*RSW 5 html javascript firefox dom mutation-observers

TL; DR

我想写一些代码来过滤掉基于新闻来源在Google新闻上显示哪些文章.


(长版)

我传统上使用Google新闻中的"个性化"选项来限制使用哪些新闻来源(例如,"不显示来自FooNews的文章").但是,个性化选项不会让您完全阻止新闻源...您可以做的最好是告诉它"很少"使用该源(它们不提供"从不"选项):

在此输入图像描述

Firefox是我的首选浏览器,所以我终于坐下来看看我是否可以编写一些代码来解决这个问题,但我想知道我的选择是什么以及可能是最好的选择.这是我到目前为止所做的/学到的:

选项1:过滤传入的数据

我做了一些谷歌搜索,看看是否有可能拦截响应数据并在浏览器中呈现之前过滤掉不需要的新闻源,但无法找到有关如何执行此操作的明确建议.使用Fiddler,我可以看到相当简单的新闻来源列表从谷歌新闻传播到浏览器,我假设页面上的一个谷歌脚本获取新闻源列表并构建HTML格式化它们根据谷歌新闻页面结构(虽然我可能错了).换句话说,我认为我看到的是响应流没有通过页面HTML发送...所有它正在做的是通过新闻源列表发送.如果是真的,那么在它甚至点击页面内格式化脚本之前简单地过滤这个新闻源流将是最简单和最简洁的.

在此输入图像描述

选项2:构造DOM 之前过滤数据

我开始摆弄Mutation Observers,看看我是否可以通过在为页面构建DOM时捕获和删除这些节点来过滤掉不需要的新闻源.我开始使用mutation-summary.js库,但是当它添加到DOM时,我没有为每个新闻文章触发事件,而是只看到一些通知.也许我做错了什么,但我需要在将每篇新闻文章添加到DOM时得到通知,以便有一个有效的过滤器.接下来我会考虑写一些普通的JS变异观察者(跳过图书馆),但是想等一下,看看是否有更好的选择.

选项3:构造DOM 之后过滤数据

我听过其他人建议这种做法:

  1. 使用CSS隐藏整个文档正文
  2. 等到构建DOM
  3. 通过查找不需要的DOM节点并删除它们来进行过滤
  4. 最后,取消隐藏修改后的正文(我猜这个技巧可以防止你在最初构建DOM后修改DOM所引起的页面闪烁)

我写了一些测试代码来尝试这种方法,虽然单调乏味,但并不难.在已经建立的Google新闻页面上研究了DOM的结构之后,我能够编写一些代码来搜索和遍历DOM以删除我不想看到的新闻文章.然而,以这种方式执行它既麻烦又繁琐,因为这会在已删除的DOM节点所在的页面结构中留下"漏洞".随着更多的工作,我可以移动其他剩余的新闻文章来填补这些"漏洞",但我宁愿使用其他方法之一,如果可能的话,因为它们似乎更容易和更清洁...更不用说更快.在构建DOM之后摆弄它需要更长的时间,因为使用CSS隐藏页面直到完成该过程会使用户等待看到任何内容,直到页面被完全加载,更改和重新显示.

这个问题

我的直觉说选项1将是最干净和最快的(如果可能的话),然后是选项2,如果没有,最后选项3作为最后的手段.

我最终希望将其转换为Firefox扩展,因此我希望我选择的解决方案具有以下特性:

  • 尽可能简单地维护代码(不是初始复杂性的问题,而是希望以后在需要进行更改以便使扩展保持最新时再次访问).理想情况下,代码将尽可能与对Google新闻页面的特定HTML格式的依赖性分离,以便每次Google调整页面时都不需要更新代码.
  • 尽可能高效(没有懈怠,页面闪烁等).我不希望用户卸载扩展程序,因为它感觉像是一块垃圾.
  • 尽可能跨浏览器(以便在将来发布Chrome,Edge等扩展程序)

在解决这个问题的所有可能的技术方法中(包括我可能错过的其他方法),哪个最符合我的要求?

Gop*_*han 1

我认为你可以很容易地完成选项 1。它与选项 3 所用的策略类似,只是您需要手动将屏幕截图中的响应隐藏到一个 off-dom dom 中进行查询(例如

var topNode = document.createElement('div'); 
div.innerHTML = response.html;
Run Code Online (Sandbox Code Playgroud)

如果需要,您可以创建一个文档片段作为多个响应的工作空间。

我认为您已经知道这一点,但为了清楚起见,下一步是查询您为源层次结构元素构建的 dom(例如,.source .source-pref对于侧边栏、.source-cell .al-attribution-source对于主要部分)。然后只需迭代节点并查找与您的违规新闻源匹配的innerText。对于匹配,请返回 dom,并删除最外面的元素。

然后将头节点的innerHTML 重新子入响应中。