Python:解码 HTML 文件中的 base64 编码字符串,并将这些字符串替换为解码后的对应字符串

Python: Decoding base64 encoded strings within an HTML file and replacing these strings with their decoded counterpart

请帮忙,因为这个翻转程序是我持续的噩梦!

我有几个文件包含一些 base64 编码的字符串。 示例文件的一部分内容如下:

charset=utf-8;base64,I2JhY2tydW5uZXJfUV81c3R7aGVpZ2h0OjkzcHg7fWJhY2tydW5uZXJfUV81c3R7ZGlzcGxheTpibG9jayFpbXBvcnRhbnQ7fQ==" 

它们的格式总是 "ANYTHINGbase64,STRING" 它是 html 但我将其视为一个大字符串并在其他地方使用 BeautifulSoup 。我正在使用正则表达式 'base' 提取 base64 字符串,然后使用 base64 模块根据我定义的函数对其进行解码 "debase".

这似乎在一定程度上工作正常:b64encode 的输出出于某种原因添加了不必要的内容:

b'#backrunner_Q_5st{height:93px;}backrunner_Q_5st{display:block!important;}' 中间的字符串。

我猜这意味着以字节为单位;所以我尝试让我的函数将其编码为 utf8,但基本上我无法理解。

我想要的最终结果是我的 html 中的所有 "base64,STRING" 都被解码并替换为 DECODEDSTRING。

请帮忙!

import os, sys, bs4, re, base64, codecs
from bs4 import BeautifulSoup

def debase(instr):
    outstring = base64.b64decode(instr)
    outstring = codecs.utf_8_encode(str(outstring))
    outstring.split("'")[1]
    return outstring

base = re.compile('base64,(.*?)"')

for eachArg in sys.argv[1:]:
    a=open(eachArg,'r',encoding='utf8')
    presoup = a.read()
    b = re.findall(base, presoup)
    for value in b:
        re.sub('base64,.*?"', debase(value))
        print(debase(value))


    soup=BeautifulSoup(presoup, 'lxml')
    bname= str(eachArg).split('.')[0]
    a.close()
    [s.extract() for s in soup('script')]
    os.remove(eachArg)
    b=open(bname +'.html','w',encoding='utf8')
    b.write(soup.prettify())
    b.close()

您的输入格式有点奇怪(例如,尾部有一个不匹配的单引号),因此请确保您没有做不必要的工作或以奇怪的方式解析内容。

无论如何,假设您以给定的形式输入,您必须按照刚才的方式使用 base64 对其进行解码,然后使用给定的编码进行解码以获取字符串而不是字节串:

import base64

inp = 'charset=utf-8;base64,I2JhY2tydW5uZXJfUV81c3R7aGVpZ2h0OjkzcHg7fWJhY2tydW5uZXJfUV81c3R7ZGlzcGxheTpibG9jayFpbXBvcnRhbnQ7fQ=="'
head,tail = inp.split(';')
_,enc = head.split('=') # TODO: check if the beginning is "charset"
_,msg = tail.split(',') # TODO: check that the beginning is "base64"

plaintext_bytes = base64.b64decode(msg)
plaintext_str = plaintext_bytes.decode(enc)

现在两个结果是

>>> plaintext_bytes
b'#backrunner_Q_5st{height:93px;}backrunner_Q_5st{display:block!important;}'
>>> plaintext_str
'#backrunner_Q_5st{height:93px;}backrunner_Q_5st{display:block!important;}'

如您所见,字节的内容已经是可读的,这是因为内容是ASCII。另请注意,我没有从您的字符串中删除尾随引号:base64 足够聪明,可以忽略内容中两个等式符号之后的内容。


简而言之,字符串是 python3 中文本的某种抽象表示,如果您想用 1 和 0 的流来表示文本,则需要特定的编码(当您将数据从一个地方传输到另一个地方)。当你得到一个以字节为单位的字符串时,你必须知道它是如何编码的,以便对其进行解码并获得正确的字符串。如果字符串是 ASCII 兼容的,那么编码是相当简单的,但是一旦出现更多的通用字符,如果您使用错误的编码,您的代码就会中断。