【问题标题】:Modify Google News to eliminate unwanted news sources修改 Google 新闻以消除不需要的新闻来源
【发布时间】:2016-11-27 00:18:58
【问题描述】:

TL;DR

我想写一些代码来根据新闻来源过滤出哪些文章显示在Google News上。


(长版)

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

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

选项 1:过滤传入数据

我做了一些谷歌搜索,看看是否有可能在浏览器中呈现之前拦截响应数据并过滤掉不需要的新闻源,但找不到任何关于如何做到这一点的明确建议。使用 Fiddler,我可以看到相当简单的新闻源列表从 Google 新闻通过网络传输到浏览器,我假设页面上的一个 Google 脚本获取该新闻源列表并构建 HTML 以格式化它们根据谷歌新闻页面结构(虽然我可能错了)。换句话说,我认为我看到的是响应流没有通过页面 HTML 发送……它所做的只是通过新闻源列表发送。如果为真,那么在新闻源流到达页内格式化脚本之前简单地过滤它是最简单和最干净的。

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

我开始摆弄MutationObservers,看看是否可以在为页面构建 DOM 时通过捕获和删除这些节点来过滤掉不需要的新闻源。我从使用 mutation-summary.js 库开始,但不是在每篇新闻文章添加到 DOM 时触发事件,而是只看到少数通知。也许我做错了什么,但是当每篇新闻文章被添加到 DOM 时,我需要得到通知,以便有一个有效的过滤器。我打算接下来写一些plain-vanilla JS mutation observers(跳过库),但想先看看是否有更好的选择。

选项 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 等的扩展)

在解决此问题的所有可能技术方法(包括我可能错过的其他方法)中,哪种方法最能满足我的要求?

【问题讨论】:

    标签: javascript html firefox dom mutation-observers


    【解决方案1】:

    我认为您可以轻松完成选项 1。这将类似于选项 3 使用的策略,只是您需要手动将屏幕截图中的响应覆盖到一个非 dom dom 中以进行查询(例如

    var topNode = document.createElement('div'); 
    div.innerHTML = response.html;
    

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

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

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

    【讨论】:

    • 从响应中创建一个文档片段以用作本地工作区是一个好主意。一旦我获取了响应的副本,有没有办法告诉页面不要进行任何渲染......基本上“坚持到我把我实际上希望你渲染的东西还给你” ?并且要替换修改后的文档片段,我是否尝试修改响应(例如,response.html = modifiedDocFragment.innerHTML)或文档(例如,document.innerHTML = modifiedDocFragment.innerHTML)?
    • 所以,老实说,我以前从未做过 chrome 插件……但我见过类似的事情。例如,我工作的一家开发商店有一个扩展程序,将“在 site_x 上检查此项目”按钮插入亚马逊页面。我相信他们在页面实际呈现之前就这样做了。我不记得按钮有任何闪烁。它就在那里。我猜你可以代理请求,并以这种方式清理他们的响应,然后将清理后的结果传递给浏览器进行渲染......我会四处看看,看看我发现了什么。
    • 所以看起来你可以使用 getURL 来获取页面内容developer.chrome.com/extensions/extension#method-getURL 然后相应地解析它。如果您愿意,您也可以使用背景页面作为您的工作区。developer.chrome.com/extensions/background_pages 这里还有一些资源:blog.lateral.io/2016/04/… 这与您想要做的相反,但使用的一些 API 将是同:stackoverflow.com/questions/16334054/…
    猜你喜欢
    • 1970-01-01
    • 2018-11-13
    • 2020-12-24
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多