我正在尝试制作此网站的离线副本:ieeghn。此任务的一部分是下载使用Beautiful Soup引用的所有css / js,并修改此新下载资源的任何外部链接。
目前我只使用字符串replace
方法。但我不认为这是有效的,因为我在循环中执行此操作,下面的代码段:
local_content = ''
for res in soup.findAll('link', {'rel': 'stylesheet'}):
if not str(res['href']).startswith('data:'):
original_res = res['href']
res['href'] = some_function_to_download_css()
local_content = local_content.replace(original_res, res['href'])
我只保存以data:
开头的非嵌入资源的资源。但问题是,local_content = local_content.replace(original_res, res['href'])
可能会导致我只能将一个外部资源修改为本地资源的问题。其余的仍然是指资源的在线版本。
我猜测因为local_content是一个非常长的字符串(看看ieeghn源代码),这样做效果不佳。
如何正确替换给定模式的字符串内容? 或者我是否必须先将其存储到文件中并在那里进行修改?
EDITED 我发现问题出在这行代码中:
original_res = res['href']
BSoup会以某种方式清理href字符串。就我而言,&
将更改为&
。当我尝试将原始href
替换为新下载的本地文件时,str.replace()
根本找不到此原始值。要么我必须找到原始HREF的方法,要么只是处理这种情况。不得不说,原来的HREF是最好的方式
答案 0 :(得分:1)
您已经在某种程度上替换了内容......
res['href'] = some_function_to_download_css()
...在BeautifulSoup的HTML树表示中更新href
节点的res
属性。
为了提高效率,您可以缓存已下载的CSS文件的URL,并在下载文件之前查阅缓存。一旦你完成了(如果你对BS的属性排序/缩进/等等没问题),你可以用str(soup)
得到树的字符串表示。
参考:http://beautiful-soup-4.readthedocs.org/en/latest/#changing-tag-names-and-attributes