用一些简单的脚本,可以很容易地清理文档和其它大量的 HTML 文件。但是首先你需要解析它们。

作为 Scribus 文档团队的长期成员,我要随时了解***的源代码更新,以便对文档进行更新和补充。 我最近在刚升级到 Fedora 27 系统的计算机上使用 Subversion 进行检出操作时,对于下载该文档所需要的时间我感到很惊讶,文档由 HTML 页面和相关图像组成。 我恐怕该项目的文档看起来比项目本身大得多,并且怀疑其中的一些内容是“僵尸”文档——不再使用的 HTML 文件以及 HTML 中无法访问到的图像。

我决定为自己创建一个项目来解决这个问题。 一种方法是搜索未使用的现有图像文件。 如果我可以扫描所有 HTML 文件中的图像引用,然后将该列表与实际图像文件进行比较,那么我可能会看到不匹配的文件。

这是一个典型的图像标签:

我对 src= 之后的***组引号之间的部分很感兴趣。 在寻找了一些解决方案后,我找到一个名为 BeautifulSoup 的 Python 模块。 脚本的核心部分如下所示:

soup=BeautifulSoup(all_text,'html.parser')

match=soup.findAll("img")

iflen(match)>0:

forminmatch:

imagelist.append(str(m))

我们可以使用这个 findAll 方法来挖出图片标签。 这是一小部分输出:

到现在为止还挺好。我原以为下一步就可以搞定了,但是当我在脚本中尝试了一些字符串方法时,它返回了有关标记的错误而不是字符串的错误。 我将输出保存到一个文件中,并在 KWrite 中进行编辑。 KWrite 的一个好处是你可以使用正则表达式(regex)来做“查找和替换”操作,所以我可以用 \n

但我认为,肯定有比这更好的东西,所以我转而使用正则表达式,或者更具体地说 Python 的 re 模块。 这个新脚本的相关部分如下所示:

match=re.findall(r'src="(.*)/>',all_text)

iflen(match)>0:

forminmatch:

imagelist.append(m)

它的一小部分输出如下所示:

images/cmcanvas.png" title="ContextMenuforthe document canvas" alt="ContextMenuforthe document canvas" />

乍一看,它看起来与上面的输出类似,并且附带有去除图像的标签部分的好处,但是有令人费解的是还夹杂着表格标签和其他内容。 我认为这涉及到这个正则表达式 src="(.*)/>,这被称为贪婪,意味着它不一定停止在遇到 /> 的***个实例。我应该补充一点,我也尝试过 src="(.*)",这真的没有什么更好的效果,我不是一个正则表达式专家(只是做了这个),找了各种方法来改进这一点但是并没什么用。

做了一系列的事情之后,甚至尝试了 Perl 的 HTML::Parser 模块,最终我试图将这与我为 Scribus 编写的一些脚本进行比较,这些脚本逐个字符的分析文本内容,然后采取一些行动。 为了最终目的,我终于想出了所有这些方法,并且完全不需要正则表达式或 HTML 解析器。 让我们回到展示的那个 img 标签的例子。

我决定回到 src= 这一块。 一种方法是等待 s 出现,然后看下一个字符是否是 r,下一个是 c,下一个是否 =。 如果是这样,那就匹配上了! 那么两个双引号之间的内容就是我所需要的。 这种方法的问题在于需要连续识别上面这样的结构。 一种查看代表一行 HTML 文本的字符串的方法是:

forcinall_text:

但是这个逻辑太乱了,以至于不能持续匹配到前面的 c,还有之前的字符,更之前的字符,更更之前的字符。

***,我决定专注于 = 并使用索引方法,以便我可以轻松地引用字符串中的任何先前或将来的字符。 这里是搜索部分:

index=3

whileindex

if(all_text[index]=='='):

if(all_text[index-3]=='s')and(all_text[index-2]=='r')and(all_text[index-1]=='c'):

imagefound(all_text,imagelist,index)

index+=1

else:

index+=1

else:

index+=1

我用第四个字符开始搜索(索引从 0 开始),所以我在下面没有出现索引错误,并且实际上,在每一行的第四个字符之前不会有等号。 ***个测试是看字符串中是否出现了 =,如果没有,我们就会前进。 如果我们确实看到一个等号,那么我们会看前三个字符是否是 s、r 和 c。 如果全都匹配了,就调用函数 imagefound:

defimagefound(all_text,imagelist,index):

end=0

index+=2

newimage=''

whileend==0:

if(all_text[index]!='"'):

newimage=newimage+all_text[index]

index+=1

else:

newimage=newimage+'\n'

imagelist.append(newimage)

end=1

return

我们给函数发送当前索引,它代表着 =。 我们知道下一个字符将会是 ",所以我们跳过两个字符,并开始向名为 newimage 的控制字符串添加字符,直到我们发现下一个 ",此时我们完成了一次匹配。 我们将字符串加一个换行符(\n)添加到列表 imagelist 中并返回(return),请记住,在剩余的这个 HTML 字符串中可能会有更多图片标签,所以我们马上回到搜索循环中。

以下是我们的输出现在的样子:

images/text-frame-link.png

images/text-frame-unlink.png

images/gimpoptions1.png

images/gimpoptions3.png

images/gimpoptions2.png

images/fontpref3.png

images/font-subst.png

images/fontpref2.png

images/fontpref1.png

images/dtp-studio.png

啊,干净多了,而这只花费几秒钟的时间。 我本可以将索引前移 7 步来剪切 images/ 部分,但我更愿意把这个部分保存下来,以确保我没有剪切掉图像文件名的***个字母,这很容易用 KWrite 编辑成功 —— 你甚至不需要正则表达式。 做完这些并保存文件后,下一步就是运行我编写的另一个脚本 sortlist.py:

#!/usr/bin/envpython

#-*-coding:utf-8-*-

#sortlist.py

importos

imagelist=[]

forlineinopen('/tmp/imagelist_parse4.txt').xreadlines():

imagelist.append(line)

imagelist.sort()

outfile=open('/tmp/imagelist_parse4_sorted.txt','w')

outfile.writelines(imagelist)

outfile.close()

这会读取文件内容,并存储为列表,对其排序,然后另存为另一个文件。 之后,我可以做到以下几点:

ls/home/gregp/development/Scribus15x/doc/en/images/*.png > '/tmp/actual_images.txt'

然后我需要在该文件上运行 sortlist.py,因为 ls 方法的排序与 Python 不同。 我原本可以在这些文件上运行比较脚本,但我更愿意以可视方式进行操作。 ***,我成功找到了 42 个图像,这些图像没有来自文档的 HTML 引用。

这是我的完整解析脚本:

#!/usr/bin/envpython

#-*-coding:utf-8-*-

#parseimg4.py

importos

defimagefound(all_text,imagelist,index):

end=0

index+=2

newimage=''

whileend==0:

if(all_text[index]!='"'):

newimage=newimage+all_text[index]

index+=1

else:

newimage=newimage+'\n'

imagelist.append(newimage)

end=1

return

htmlnames=[]

imagelist=[]

tempstring=''

filenames=os.listdir('/home/gregp/development/Scribus15x/doc/en/')

fornameinfilenames:

ifname.endswith('.html'):

htmlnames.append(name)

#printhtmlnames

forhtmlfileinhtmlnames:

all_text=open('/home/gregp/development/Scribus15x/doc/en/'+htmlfile).read()

linelength=len(all_text)

index=3

whileindex

if(all_text[index]=='='):

if(all_text[index-3]=='s')and(all_text[index-2]=='r')and

(all_text[index-1]=='c'):

imagefound(all_text,imagelist,index)

index+=1

else:

index+=1

else:

index+=1

outfile=open('/tmp/imagelist_parse4.txt','w')

outfile.writelines(imagelist)

outfile.close()

imageno=len(imagelist)

printstr(imageno)+" images were found and saved"

脚本名称为 parseimg4.py,这并不能真实反映我陆续编写的脚本数量(包括微调的和大改的以及丢弃并重新开始写的)。 请注意,我已经对这些目录和文件名进行了硬编码,但是很容易变得通用化,让用户输入这些信息。 同样,因为它们是工作脚本,所以我将输出发送到 /tmp 目录,所以一旦重新启动系统,它们就会消失。

这不是故事的结尾,因为下一个问题是:僵尸 HTML 文件怎么办? 任何未使用的文件都可能会引用图像,不能被前面的方法所找出。 我们有一个 menu.xml 文件作为联机手册的目录,但我还需要考虑 TOC(LCTT 译注:TOC 是 table of contents 的缩写)中列出的某些文件可能引用了不在 TOC 中的文件,是的,我确实找到了一些这样的文件。

***我可以说,这是一个比图像搜索更简单的任务,而且开发的过程对我有很大的帮助。

【编辑推荐】

【责任编辑:庞桂玉 TEL:(010)68476606】

点赞 0

python分析html文件_如何用Python解析HTML?相关推荐

  1. python分析每月销售数据_如何用Python分析销售数据

    数据分析的基本过程分为五个部分:提出问题.理解数据.数据清洗.构建模型.数据可视化.下面我以前四部分为基础,对一个销售数据进行分析. 1 提出问题 分析目标:根据以下三个业务指标分析医院的销售情况:月 ...

  2. python情绪分析的意义_如何用Python和R对故事情节做情绪分析?

    想知道一部没看过的影视剧能否符合自己口味,却又怕被剧透?没关系,我们可以用情绪分析来了解故事情节是否足够跌宕起伏.本文一步步教你如何用Python和R轻松愉快完成文本情绪分析.一起来试试吧. 烦恼 追 ...

  3. python怎样打开加密的文件_如何用Python 加密文件

    生活中,有时候我们需要对一些重要的文件进行加密,Python 提供了诸如 hashlib,base64 等便于使用的加密库. 但对于日常学习而言,我们可以借助异或操作,实现一个简单的文件加密程序,从而 ...

  4. python 读取excel图片_如何用Python读取Excel中图片?

    公众号: 早起Python 作者:刘早起 大家好,在使用Python进行办公自动化操作时,一定少不了与Excel表格的交互,我们通常是用pandas处理表格数据,但大多数情况下,都是读取表格中的数值进 ...

  5. 怎么用python读取excel图_如何用Python读取Excel中图片?

    公众号: 早起Python 作者:刘早起 大家好,在使用Python进行办公自动化操作时,一定少不了与Excel表格的交互,我们通常是用pandas处理表格数据,但大多数情况下,都是读取表格中的数值进 ...

  6. python编程代码画画_如何用python编写一个绘制马赛克图像的自写程序

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 这篇教程将会展示如何用python的图形化包"Pygame"和基础的文件I/O来创建一 ...

  7. python 文本翻译 项目_如何用python批量翻译文本?

    首先,看一下百度翻译的官方api文档. http://api.fanyi.baidu.com/api/trans/product/apidoc # coding=utf-8 #authority:bi ...

  8. python 登陆淘宝_如何用 Python 自动登录淘宝并保存登录信息?

    原标题:如何用 Python 自动登录淘宝并保存登录信息? 作者 | 猪哥 责编 | 伍杏玲 前段时间时间为大家讲解了如何使用requests库模拟登录淘宝,而今天我们将对该功能进行丰富.所以我们把之 ...

  9. python怎么做数据分析_如何用python进行数据分析

    1.Python数据分析流程及学习路径 数据分析的流程概括起来主要是:读写.处理计算.分析建模和可视化四个部分.在不同的步骤中会用到不同的Python工具.每一步的主题也包含众多内容. 根据每个部分需 ...

  10. 用python做一张图片_如何用python下载一张图片

    如何用python下载一张图片 这里要用到的主要工具是requests这个工具,需要先安装这个库才能使用,该库衍生自urllib这个库,但是要比它更好用.多数人在做爬虫的时候选择它,是个不错的选择. ...

最新文章

  1. java学习与总结:反射及动态代理
  2. 关于域帐户将计算机加入域登陆上限问题
  3. redis 源码 object.c 实现
  4. CF思维联系– CodeForces - 991C Candies(二分)
  5. vuex使用及自定义Vue指令vue-permission
  6. 如果时光倒流,我会这样学java
  7. 中国1-4级行政区划分数据表(从国家统计局获得) MySQL
  8. 网站添加cdn加速服务器,网站使用腾讯云cdn加速操作实战
  9. 求有限区间内素数个数
  10. 上海始终未出现真正“富人区”
  11. aws php sns,使用 AWS SNS 发送通知到 HTTP 终端
  12. Rails——migration
  13. 云计算的1024种玩法——如何快速搭建个人博客?
  14. JavaWeb中外部引入的js中涉及到location.href的页面跳转/jsp页面的外部js文件引入
  15. Centos挂载fat32格式的u盘和ntfs格式的移动硬盘
  16. 项目管理:如何使用甘特图制定项目计划
  17. CISSP-D2-资产安全
  18. 虚拟实验工场计算机科学导论论文,计算机科学导论论文
  19. riak教程 java_Riak学习(2):java连接Riak服务,使用Protocol Buffers连接
  20. 多语言的测试注意事项

热门文章

  1. 软考错题合集之12-11-AM
  2. 学习总结 java 父子级
  3. BestCoder Round #66 (div.2)B GTW likes gt
  4. XNA开发—渲染对象
  5. Compiz Check测试Linux桌面3D兼容性
  6. 标 题: 三维游戏里面的自动寻路的算法可能是什么样的?
  7. Treo 650使用专题及开发计划等
  8. MyCat分片规则之程序指定分片
  9. 15张图带你彻底明白spring循环依赖,再也不用怕了
  10. 堆排序(C语言实现)