【问题标题】:How to decode Angular's custom HTML encoding with Python如何使用 Python 解码 Angular 的自定义 HTML 编码
【发布时间】:2021-07-06 08:24:20
【问题描述】:

我想抓取并解析一个London Stock Exchange news article

网站的几乎所有内容都来自JSON,而JavaScript 使用了该JSON。但是,可以使用BeautifulSoup 轻松提取并使用JSON 模块进行解析。

但是脚本的编码有点古怪。

<script> 标记有一个 id"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() 链来处理这个问题:

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;amp;a;#160;
  • &amp;amp;a;amp;
  • &amp;amp;s;

仅举几例。

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

【问题讨论】:

  • 相关:stackoverflow.com/questions/62127215/… 同样的问题,同样的网站。
  • 感谢@QHarr 指出这一点。似乎我们都可以从比.replace() 方法链更通用的解决方案中受益。

标签: python angular parsing web-scraping beautifulsoup


【解决方案1】:

Angular 使用位于here 的特殊转义函数对transfer state 进行编码:

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]);
}

您可以在python中重现unescapeHtml函数,并添加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"))

你错过了&amp;s;&amp;a;

repl.it:https://replit.com/@bertrandmartel/AngularTransferStateDecode

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 2011-08-11
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多