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

时间:2018-04-20 10:59:08

标签: python html beautifulsoup base64 decoding

请帮助,因为这个翻转计划是我持续的噩梦!

我有几个包含一些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()

1 个答案:

答案 0 :(得分:2)

您的输入格式有点奇怪(例如,带有无法匹配的单引号),因此请确保您不会以奇怪的方式进行不必要的工作或解析内容。

无论如何,假设你输入的形式是你给出的,你必须使用base64以你刚才的方式解码它,然后用给定的编码解码得到一个字符串而不是一个字节串: / p>

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足够聪明,可以忽略内容中两个等式符号后的内容。

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