文档编码TXT,CSV,PDF的相关使用DIY

文档编码

文档编码是一种告诉程序——无论是计算机的操作系统还是 Python 代码——读取文档的规则。文档编码的方式通常可以根据文件的扩展名进行判断,虽然文件扩展名并不是由编码确定的,而是由开发者确定的。例如,如果我把 myImage.jpg 另存为 myImage.txt,不会出现任何问题,但当我用文本编辑器打开它的时候就有问题了。好在这种情况很少见,如果要正确地读取一个文档,必须要知道它的扩展名。
从最底层的角度看,所有文档都是由 0 和 1 编码而成的。而在高层(贴近用户的层级),编码算法会定义“每个字符多少位”或“每个像素的颜色值用多少位”(图像文件里)之类的事情,在那里你会遇到一些数据压缩算法或体积缩减算法,比如 PNG 图像编码格式(一种无损压缩的位图图形格式)。
虽然第一次处理这些非 HTML 格式的文件时会觉得很没底,但是只要安装了合适的库,Python 就可以帮你处理任意类型的文档。纯文本文件、视频文件和图像文件的唯一区别,就是它们的 0 和 1 面向用户的转换方式不同。
虽然把文件存储为在线的纯文本格式并不常见,但是一些简易网站,或者拥有大量纯文本文件的“旧式学术”(old-school)网站经常会这么做。例如,互联网工程任务组(Internet Engineering Task Force,IETF)网站就存储了 IETF 发表过的所有文档,包含 HTML、PDF和纯文本格式(例如 https://www.ietf.org/rfc/rfc1149.txt)。大多数浏览器都可以很好地显示纯文本文件,采集它们也不会遇到什么问题。
对大多数简单的纯文本文件,像 http://www.pythonscraping.com/pages/warandpeace/chapter1.
txt 这个练习文件,你可以用下面的方法读取

from urllib.request import urlopen
textPage = urlopen(
 "http://www.pythonscraping.com/pages/warandpeace/chapter1.txt")
print(textPage.read())

通常,当用 urlopen 获取了网页之后,我们会把它转变成 BeautifulSoup 对象,方便后面对 HTML 进行分析。在这段代码中,我们直接读取页面内容。你可能觉得,如果把它转变成 BeautifulSoup 对象应该也不错,但那样做其实适得其反——这个页面不是 HTML,所以BeautifulSoup 库就没用了。一旦纯文本文件被读成字符串,你就只能用普通 Python 字符串的方法分析它了。当然,这么做有个缺点,就是你不能对字符串使用 HTML 标签,去定位那些你真正需要的文字,避开那些你不需要的文字。如果现在你想从纯文本文件中抽取某些信息,还是有些难度的。
处理 HTML 页面的时候,网站其实会在 部分显示页面使用的编码格式。大多数网站,尤其是英文网站,都会带这样的标签:

而 ECMA(European Computer Manufacturers Association,欧洲计算机制造商协会,http:// www.ecma-international.org/)网站的标签是这样 : 如果你要做很多网络数据采集工作,尤其是面对国际网站时,建议你先看看 meta 标签的内容,用网站推荐的编码方式读取页面内容。其他省略。

CSV 文件

进行网页采集的时候,你可能会遇到 CSV 文件,也可能有同事希望将数据保存为 CSV格式。Python 有一个超赞的标准库(https://docs.python.org/3.4/library/csv.html)可以读写
CSV 文件。虽然这个库可以处理各种 CSV 文件,但是这里我重点介绍标准 CSV 格式。如果你在处理 CSV 时有特殊需求,请查看文档
Python 的 csv 库主要是面向本地文件,就是说你的 CSV 文件得存储在你的电脑上。而进行网络数据采集的时候,很多文件都是在线的。不过有一些方法可以解决这个问题:
• 手动把 CSV 文件下载到本机,然后用 Python 定位文件位置;
• 写 Python 程序下载文件,读取之后再把源文件删除;
• 从网上直接把文件读成一个字符串,然后转换成一个 StringIO 对象,使它具有文件的属性。
虽然前两个方法也可以,但是既然你可以轻易地把 CSV 文件保存在内存里,就不要再下载到本地占硬盘空间了。直接把文件读成字符串,然后封装成 StringIO 对象,让Python 把它当作文件来处理,就不需要先保存成文件了。下面的程序就是从网上获取一个CSV 文件(这里用的是 http://pythonscraping.com/files/MontyPythonAlbums.csv 里的 Monty Python 乐团的专辑列表),然后把每一行都打印到命令行里

from urllib.request import urlopen
from io import StringIO
import csv
data = urlopen("http://pythonscraping.com/files/MontyPythonAlbums.csv")
 .read().decode('ascii', 'ignore')
dataFile = StringIO(data)
csvReader = csv.reader(dataFile)
for row in csvReader:
 print(row)

显示结果很长,开始部分是这样:

['Name', 'Year']
["Monty Python's Flying Circus", '1970']
['Another Monty Python Record', '1971']
["Monty Python's Previous Record", '1972'

注意看第一行的内容,The album “Name” was released in Year。虽然写示例代码的时候,
这行内容是否显示都无所谓,但是工作中你肯定不希望将这行信息保留在数据里。有些程
序员可能会简单地跳过 csvReader 对象的第一行,或者写一个简单的条件把第一行处理掉。
不过,还有一个函数可以很好地处理这个问题,那就是

csv.DictReader:
from urllib.request import urlopen
from io import StringIO
import csv
data = urlopen("http://pythonscraping.com/files/MontyPythonAlbums.csv")
 .read().decode('ascii', 'ignore')
dataFile = StringIO(data)
dictReader = csv.DictReader(dataFile)
print(dictReader.fieldnames)
for row in dictReader:
 print(row)

csv.DictReader 会返回把 CSV 文件每一行转换成 Python 的字典对象返回,而不是列表对象,并把字段列表保存在变量 dictReader.fieldnames 里,字段列表同时作为字典对象的键。

['Name', 'Year']
{'Name': "Monty Python's Flying Circus", 'Year': '1970'}
{'Name': 'Another Monty Python Record', 'Year': '1971'}
{'Name': "Monty Python's Previous Record", 'Year': '1972'}

虽然用 DictReaders 创建、处理和打印 CSV 信息,比 csvReaders 要多写一点儿代码,但是考虑到它的便利性和实用性,多写那点儿代码还是值得的

PDF 显示

从某种意义上说,Adobe在 1993 年发明 PDF 格式(Portable Document Format,便携式文档格式)是一种技术革命。
PDF 可以让用户在不同的系统上用同样的方式查看图片和文本文档,无论这些文件是在哪种系统上制作的。
虽然把 PDF 显示在网页上已经有点儿过时了(你已经可以把内容显示成 HTML 了,为什
么还要用这种静态、加载速度超慢的格式呢?),但是 PDF 仍然无处不在,尤其是在处理商务报表和表单的时候。
2009 年,一个叫 Nick Innes 的英国人上了新闻,他根据英联邦的信息自由法案,要求英国白金汉郡议会公开学生的考试成绩。在几次请求遭到拒绝之后,他开始自己收集信息——最后收集了 184 份 PDF 文件。
虽然 Innes 努力坚持,并且最后得到了一个格式更好的数据库,但是如果他事先了解网络爬虫,再用 Python 众多PDF 解析模块中的任意一个来处理这些 PDF 文件,那么他一定可以在法庭上节省很多时间。
不过目前很多 PDF 解析库都是用 Python 2.x 版本建立的,还没有迁移到 Python 3.x 版本。但是,因为 PDF 比较简单,而且是开源的文档格式,所以有一些给力的 Python 库可以读取 PDF 文件,而且支持 Python 3.x 版本。
PDFMiner3K 就是一个非常好用的库(是 PDFMiner 的 Python 3.x 移植版)。它非常灵活,可以通过命令行使用,也可以整合到代码中。它还可以处理不同的语言编码,而且对网络文件的处理也非常方便。
你可以下载这个模块的源文件(https://pypi.python.org/pypi/pdfminer3k),解压并用下面命令安装:
$python setup.py install
文档位于源文件解压文件夹的 /pdfminer3k-1.3.0/docs/index.html 里
下面的例子可以把任意 PDF 读成字符串,然后用 StringIO 转换成文件对象

from urllib.request import urlopen
from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from io import StringIO
from io import open
def readPDF(pdfFile):
 rsrcmgr = PDFResourceManager()
 retstr = StringIO()
 laparams = LAParams()
 device = TextConverter(rsrcmgr, retstr, laparams=laparams)
 process_pdf(rsrcmgr, device, pdfFile)
 device.close()
 content = retstr.getvalue()
 retstr.close()
 return content
pdfFile = urlopen("http://pythonscraping.com/pages/warandpeace/chapter1.pdf")
outputString = readPDF(pdfFile)
print(outputString)
pdfFile.close()

readPDF 函数最大的好处是,如果你的 PDF 文件在电脑里,你就可以直接把 urlopen 返回的对象 pdfFile 替换成普通的 open() 文件对象:
pdfFile = open("…/pages/warandpeace/chapter1.pdf", ‘rb’)
输出结果可能不是很完美,尤其是当 PDF 里有图片、各种各样的文本格式,或者带有表格和数据图的时候。但是,对大多数只包含纯文本内容的 PDF 而言,其输出结果与纯文本格式基本没什么区别

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海宝7号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值