如何使用 Python 解码 Angular 的自定义 HTML 编码

2024-02-06

我想抓取并解析伦敦证券交易所新闻文章 https://www.londonstockexchange.com/news-article/ESNT/date-for-fy-2020-results-announcement/14850033.

网站的全部内容几乎都来自于JSON消耗的JavaScript。然而,这可以很容易地提取出来BeautifulSoup并解析为JSON module.

但脚本的编码有点奇怪。

The <script>标签有一个id of "ng-lseg-state",这意味着这是 Angular 的自定义 HTML 编码。

例如:

&l;div class=\"news-body-content\"&g;&l;html xmlns=\"http://www.w3.org/1999/xhtml\"&g;\n&l;head&g;\n&l;meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /&g;\n&l;title&g;&l;/title&g;\n&l;meta name=\"generator\"

我用一个来处理这个.replace() chain:

import json

import requests
from bs4 import BeautifulSoup

url = "https://www.londonstockexchange.com/news-article/ESNT/date-for-fy-2020-results-announcement/14850033"
script = BeautifulSoup(requests.get(url).text, "lxml").find("script", {"id": "ng-lseg-state"})
article = json.loads(script.string.replace("&q;", '"'))
main_key = "G.{{api_endpoint}}/api/v1/pages?parameters=newsId%3D14850033&a;path=news-article"
article_body = article[main_key]["body"]["components"][1]["content"]["newsArticle"]["value"]
decoded_body = (
    article_body
    .replace('&l;', '<')
    .replace('&g;', '>')
    .replace('&q;', '"')
)
print(BeautifulSoup(decoded_body, "lxml").find_all("p"))

但仍然有一些字符我不知道如何处理:

  • &amp;a;#160;
  • &amp;a;amp;
  • &amp;s;

仅举几个。

那么,问题是,我该如何处理其余的字符?或者也许有一个我不知道的解析器或可靠的字符映射?


角度编码转移状态 https://angular.io/api/platform-browser/TransferState使用位于的特殊转义函数here https://github.com/angular/angular/blob/61bfa3d9dfc7c9daecde098aca595b731c3312a0/packages/platform-browser/src/browser/transfer_state.ts#L12-L32:

export function escapeHtml(text: string): string {
  const escapedText: {[k: string]: string} = {
    '&': '&a;',
    '"': '&q;',
    '\'': '&s;',
    '<': '&l;',
    '>': '&g;',
  };
  return text.replace(/[&"'<>]/g, s => escapedText[s]);
}

export function unescapeHtml(text: string): string {
  const unescapedText: {[k: string]: string} = {
    '&a;': '&',
    '&q;': '"',
    '&s;': '\'',
    '&l;': '<',
    '&g;': '>',
  };
  return text.replace(/&[^;]+;/g, s => unescapedText[s]);
}

您可以重现unescapeHtmlpython 中的函数,并添加html.unescape解析额外的 html 实体:

import json
import requests
from bs4 import BeautifulSoup
import html

unescapedText = {
    '&a;': '&',
    '&q;': '"',
    '&s;': '\'',
    '&l;': '<',
    '&g;': '>',
}

def unescape(str):
    for key, value in unescapedText.items():
        str = str.replace(key, value)
    return html.unescape(str)

url = "https://www.londonstockexchange.com/news-article/ESNT/date-for-fy-2020-results-announcement/14850033"
script = BeautifulSoup(requests.get(url).text, "lxml").find("script", {
    "id": "ng-lseg-state"
})
payload = json.loads(unescape(script.string))
main_key = "G.{{api_endpoint}}/api/v1/pages?parameters=newsId%3D14850033&path=news-article"
article_body = payload[main_key]["body"]["components"][1]["content"]["newsArticle"]["value"]
print(BeautifulSoup(article_body, "lxml").find_all("p"))

你失踪了&s; and &a;

复制它:https://replit.com/@bertrandmartel/AngularTransferStateDecode https://replit.com/@bertrandmartel/AngularTransferStateDecode

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Python 解码 Angular 的自定义 HTML 编码 的相关文章

随机推荐