乐趣区

关于python:爬虫系列读取-CSVPDFWord-文档

上一期咱们解说了应用 Python 读取文档编码的相干问题,本期咱们解说应用 Python 解决 CSV、PDF、Word 文档相干内容。

CSV

咱们进行网页采集的时候,你可能会遇到 CSV 文件,也可能我的项目须要将数据保留到 CSV 文件。Python 有一个超赞的规范库能够读写 CSV 文件。尽管这个库能够解决各种 CSV 文件,然而咱们这里重点介绍规范 CSV 格局。

读取 CSV 文件

Python 的 CSV 次要是面向本地用户,也就是说你的 CSV 文件得保留到你的电脑上。而经行网络数据采集的时候,很多文件都是在线的。不过有一些办法能够解决这个问题:

  • 手动把 CSV 文件下载到本机,而后用 Python 定位文件地位;
  • 写 Python 程序下载文件,读取之后把源文件删除;
  • 从网上间接把文件读取成一个字符串,而后转换成一个 StringIO 对象,使它具备文件的属性。

尽管前两个办法也能够用,然而既然你能够轻易的把 CSV 文件保留到内存里,就不要下载到本地占用硬盘空间了。间接把文件读取成字符串,而后封装成 StringIO 对象,让 Python 把他当作文件来解决,就不须要保留成文件了。上面的程序就是从网上获取一个 CSV 文件,而后把每一行都打印到命令行里:

import requests
from io import StringIO
import csv


class ProcessCSVPDFDOCX(object):
    def __init__(self):
        self._csv_path = 'https://image.pdflibr.com/crawler/blog/country.CSV'
        self._session = requests.Session()

    def read_csv(self):
        response = self._session.get(self._csv_path)
        # 将文本设置成 utf-8 的编码方式
        response.encoding = 'utf-8'
        response_text = response.text
        data_file = StringIO(response_text)
        dict_reader = csv.DictReader(data_file)

        print(dict_reader.fieldnames)

        for row in dict_reader:
            print(row)


if __name__ == '__main__':
    ProcessCSVPDFDOCX().read_csv()

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

PDF

从某种意义上来说,Adobe 在 1993 年创造 PDF 格局(Protable Document Format,便携式文档格局)是一种技术反动。PDF 能够让用户在不同零碎上应用同样的形式查看图片和文本文档,无论这种文件是在那种零碎上制作的。

尽管把 PDF 显示在网页上曾经过期了(你曾经能够把内容显示成 HTML 了,为什么还要这种动态、加载速度超慢的格局呢?),然而 PDF 依然无处不在,尤其是在解决商务报表和表单的时候。

目前很多 PDF 解析库都是 Python 2.x 版本建设的,还没有迁徙到 Python 3.x 版本。然而,因为 PDF 比较简单,而且开源的文档格局,所以一些给力的 Python 能够读取 PDF 文件,而且反对 Python 3.x 版本。

PDFMiner3K 就是一个十分好用的库(是 PDFMiner 的 Python 3.x 移植版)。他非常灵活,能够通过命令行应用,也能够整合到代码中。还能够解决不同的语言编码,而且对网络文件的解决也十分的不便。

你能够下载这个模块的源文件(https://pypi.org/project/pdfminer3k/),解压并用上面命令装置:

python setup.py install

咱们也能够应用 pip 的形式装置:

pip install pdfminer3k

上面的例子能够把任意 PDF 读成字符串,而后应用 StringIO 转换成文件对象:

import requests
from io import StringIO
import csv
from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.layout import LAParams
from pdfminer.converter import TextConverter
from urllib.request import urlopen


class ProcessCSVPDFDOCX(object):
    def __init__(self):
        self._session = requests.Session()
        self._pdf_path = 'https://image.pdflibr.com/crawler/blog/markdown-cheatsheet-online.pdf'


    def read_pdf(self, pdf_file):
        rscmgr = PDFResourceManager()
        retstr = StringIO()
        laparames = LAParams()
        device = TextConverter(rscmgr, retstr, laparams=laparames)
        process_pdf(rscmgr, device, pdf_file)
        device.close()

        content = retstr.getvalue()
        retstr.close()
        return content

    def read_pdf_main(self):
        pdf_file = urlopen(self._pdf_path)
        output_string = self.read_pdf(pdf_file)
        print(output_string)
        pdf_file.close()


if __name__ == '__main__':
    ProcessCSVPDFDOCX().read_pdf_main()

readPDF 最大的益处是,如果你的 PDF 文件在电脑里,你就能够间接把 urlopen 返回的对象 pdf_file 换成一般的 open() 文件对象。

输出的后果可能不是很完满,尤其是当文件中蕴含图片、各种各样的文本格式,或者带有表格和数据图的时候。然而,对于大多数只蕴含纯文本内容的 PDF 而言,其输入后果与纯文本并没有什么区别。

微软 Word 和 .docx

网上有很多对 Word 吐槽的网友,Word 的特意性能就是把那些因该写成简略 TXT 或 PDF 格局的文件,变成了即大又慢且难以关上的怪兽,它们常常在零碎切换和版本切换中呈现格局不兼容,而且应为某些起因在文件内容曾经定稿后仍处于可编辑状态。Word 文档从未打算让人频繁传递。不过他们在一些网站上很风行,包含重要的文档、信息,甚至图表和多媒体;总之,那些内容都应该应用 HTML 代替。

大概在 2008 年以前,微软 Office 产品中 Word 用 .doc 文件格式。这种二进制格局很难读取,而且可能读取 word 格局的软件很少。为了跟上时代,让本人的软件合乎支流软件的规范,微软决定应用 Open Office 的类 XML 格局规范,尔后新版本 Word 能力与其余文字处理软件兼容,这个格局就是 .docx

不过,Python 对这种 Google Docs、Open Office 和 Microsoft Office 都在应用的 .docx 格局反对还不够好。尽管有一个 python-docx 库,然而只反对创立和读取一些根本的数据,入文件大小和文件题目,不反对注释读取。如果想读取 Microsoft Office 文件的注释内容,咱们须要本人入手找办法。

第一步是从文件读取 XML:

import requests
from io import StringIO
import csv
from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.layout import LAParams
from pdfminer.converter import TextConverter
from urllib.request import urlopen
from io import open, BytesIO
from zipfile import ZipFile


class ProcessCSVPDFDOCX(object):
    def __init__(self):
        self._csv_path = 'https://image.pdflibr.com/crawler/blog/country.CSV'
        self._session = requests.Session()
        self._pdf_path = 'https://image.pdflibr.com/crawler/blog/markdown-cheatsheet-online.pdf'
        self._docx_path = 'https://image.pdflibr.com/crawler/blog/test_document.docx'

  
    def convert_docx_to_xml(self):
        word_file = urlopen(self._docx_path).read()
        word_file = BytesIO(word_file)
        document = ZipFile(word_file)
        xml_content = document.read('word/document.xml')
        print(xml_content.decode('utf-8'))


if __name__ == '__main__':
    ProcessCSVPDFDOCX().convert_docx_to_xml()

这段代码把近程 Word 读取成一个二进制文件对象(BytesIO 与下面应用的 StringIO 相似),再应用 Python 的规范库 zipfile 解压(所有的 .docx 文件为了节俭空间都进行了压缩),而后对读取这个解压文件,就变成了 XML 了。

解压后的 XML 文件蕴含了大量信息,好在所有的内容都蕴含在 <w:t> 标签外面,题目内容也是如此,这样就容易解决多了。

import requests
from io import StringIO
import csv
from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.layout import LAParams
from pdfminer.converter import TextConverter
from urllib.request import urlopen
from io import open, BytesIO
from zipfile import ZipFile
from bs4 import BeautifulSoup


class ProcessCSVPDFDOCX(object):
    def __init__(self):
        self._csv_path = 'https://image.pdflibr.com/crawler/blog/country.CSV'
        self._session = requests.Session()
        self._pdf_path = 'https://image.pdflibr.com/crawler/blog/markdown-cheatsheet-online.pdf'
        self._docx_path = 'https://image.pdflibr.com/crawler/blog/test_document.docx'


    def convert_docx_to_xml(self):
        word_file = urlopen(self._docx_path).read()
        word_file = BytesIO(word_file)
        document = ZipFile(word_file)
        xml_content = document.read('word/document.xml')
        print(xml_content.decode('utf-8'))
        word_obj = BeautifulSoup(xml_content.decode('utf-8'), features="html.parser")
        text_string = word_obj.findAll("w:t")
        for text_ele in text_string:
            print(text_ele.text)


if __name__ == '__main__':
    ProcessCSVPDFDOCX().convert_docx_to_xml()

这段代码显示的后果可能并不完满,然而曾经差不多了,一行打印一个 <w:t> 标签。

总结

这篇文章次要解说了应用 Python 如何解决在线 CSV、PDF、Word 文档,因为 docx 文档并没有很好的库,如何曲线解析 docx 文件,通过这篇文章能够解决互联网上大部分文档内容。

这篇文章的所有源代码曾经托管于 Github: https://github.com/sycct/Scra…

如果有任何问题,欢送大家 issue。

退出移动版