本·拉登的書架:Python文本分析拉登最常唸叨什麼?

本文首發於編程派的微信公衆號,搜索“codingpy”關注編程派吧。

2015年,美國官方解密了一系列有關本·拉登的文件,其中最引人矚目的,是美國國家情報總監辦公室(The Office of the Director of National Intelligence)在其官網上列出的“本·拉登的書架”。

曝光的這份閱讀清單涉及書籍和其他材料400餘種。其中包含了已解密的書信等文檔103份、公開發表的美國政府文件75份、英文書籍39冊、恐怖組織發表的材料35份、與法國有關的材料19份、媒體文章33篇、其他宗教文檔11份、智庫或其他研究40種、軟件或技術手冊30份,及一些零散資料。

在本文中,我們將學習如何分析PDF文檔,並且利用AlchemyAPI來進行實體抽取分析,看看本·拉登在這些信件中最常提到的10個實體是什麼。

AlchemyAPI是IBM旗下的一家公司,具有深度學習的自然語言處理和圖片識別技術,可利用人工智能分析理解網頁、文檔、電子郵件、微博等形式的內容。它還將同Google 一樣的神經網絡分析技術應用其中。

AlchemyAPI目前共提供了12個文本分析功能:實體抽取(entitiy extraction),情感分析,關鍵字抓取,概念標識,關係提取,分類識別,作者提取,語言識別,文本提取,微格式分析,訂閱內容識別,數據連接等。

接下來,我們開始進行準備工作。

本文中的代碼大部分來自automatingosint,我對源代碼進行更新。目前的腳本支持Python 3。

安裝依賴包

由於美國ODNI公開的本·拉登信件都是PDF格式的,因此我們首先必須要安裝能夠處理PDF文檔的Python包。這裏,我使用的是PyPDF2。我們通過pip包管理器進行安裝:

pip install pypdf2

另外,你肯定不想一封一封地手動103封書信吧?!省時省力的辦法就是寫個腳本把這些文檔都爬取下來。由於要訪問網頁和解析網頁,我們選擇使用兩個常用的第三方庫:requests和BeautifulSoup 4:

pip install requests beautifulsoup4

獲取免費AlchemyAPI Key

AlchemyAPI是IBM旗下的一家公司,具有深度學習的自然語言處理和圖片識別技術,可利用人工智能分析理解網頁、文檔、電子郵件、微博等形式的內容。它還將同Google 一樣的神經網絡分析技術應用其中。AlchemyAPI目前共提供了12個文本分析功能:實體抽取(entitiy extraction),情感分析,關鍵字抓取,概念標識,關係提取,分類識別,作者提取,語言識別,文本提取,微格式分析,訂閱內容識別,數據連接等。

AlchemyAPI有一個免費的基礎服務包,每天的事務處理上限爲1000次。在本文中,我們將使用他們的實體抽取服務來執行文本分析。

獲取免費AlchemyAPI Key非常簡單,只需要填寫一個表單即可,輸入自己的郵箱地址。

申請處理完成之後,你就可以在郵箱中看到發送給你的API Key了。

AlchemyAPI Key申請郵件回覆

安裝Alchemy Python SDK

獲得API Key之後,我們可以通過AlchemyAPI提供的Python SDK和HTTP REST接口調用其提供的文本分析服務。在本文中,我們選擇安裝SDK的方式。

PyPI上之前有AlchemyAPI包,但是後來移除了下載包,因此我們不能使用pip來安裝,只能通過Git克隆Python SDK的代碼庫或是直接下載代碼庫:

git clone https://github.com/AlchemyAPI/alchemyapi_python.git

接下來,我們要把申請到的API Key與SDK關聯起來。打開終端,進入SDK文件夾,然後按下面的示例執行alchemyapi.py文件:

cd alchemyapi_python
python alchemyapi.py YOUR_API_KEY # 將YOUR_API_KEY替換成你收到的Key

爲確保SDK正常安裝,可以按照提示運行example.py查看演示程序:

python example.py

如果最後出現了下圖的文字,就證明SDK安裝正確,API Key也可以使用。

AlchemyAPI安裝正常

下載文檔

然後就到了怎麼自動將103份PDF文檔下載到本地了。

我們可以寫一個簡單的Python腳本來完成這項工作,但是我選擇把它封裝在download_bld_documents這個函數裏,因爲我想把所有的代碼都放在一個腳本里,這樣大家就可以直接運行這個腳本,等待一段時間,就可以看到最後的結果了。

這個函數寫的比較簡單,但是已經能夠滿足我們的需求了。

def download_bld_documents():
    """Download Bin Laden's Declassified documents from ODNI."""
    import os
    import time
    import requests    
    from bs4 import BeautifulSoup

    # 創建一個名爲“pdfs”的文件夾,用於保存所有下載的PDF文檔。
    try:
        os.mkdir("pdfs")
    except:
        pass

    # 獲取ODNI網站上有關本·拉登書架的網頁,
    # 將其交給Beautiful Soup,以進行HTML解析。
    response = requests.get(
        "http://www.dni.gov/index.php/resources/bin-laden-bookshelf?start=1")

    if response.status_code == 200:

        html = BeautifulSoup(response.content)

    link_list = []
    # 從網頁中第54個超鏈接開始,我們遍歷所有的文檔鏈接,
    # 僅保留那些我們所需要的鏈接:即含有“pdf”但不包含“Arabic
    # 字樣的鏈接。我們將滿足要求的鏈接保存到列表`link_list`中。

    for i in html.findAll("a")[54:]:
        if "pdf" in i['href'] and "Arabic" not in i.text:
            link_list.append("http://www.odni.gov%s" % i['href'])
    # 接下來,我們遍歷列表中所有的元素,
    # 從原鏈接中獲取PDF的文件名,
    #然後從ODNI網站下載相應的文檔。

    for i in link_list:
        response = requests.get(i)
        file_name = i.split("/")[::-1][0]
        fd = open("pdfs/%s" % file_name, "wb")
        fd.write(response.content)
        fd.close()

        time.sleep(1)

由於文件數量比較多,因此在最終執行腳本時,耗費在文件下載的時間可能會比較長。如果你從ODNI網站下載的速度非常慢,那麼可以前往我的百度網盤下載,但是在最終執行時要對腳本做修改。只需要執行下文中的函數即可。

在微信號中,回覆“laden”即可獲得分享鏈接及提取碼。

處理文檔

下面,我們就可以正式對下載的PDF文檔進行分析了。我們將要利用Alchemy API提供的強大工具,對這些PDF文檔進行實體抽取(entitiy extraction)分析。通過實體分析,我們可以瞭解本·拉登在這些信件和文件中,談到最多的人、地方或東西是什麼。

所以,我們要一一打開這些PDF文件,從文檔中提取所有的文本,然後將其提交至Alchemy進行分析處理。在處理每一個文檔時,我們可以得到其中的實體數據,最後將所有文檔的分析數據結合在一起,就可以得到出現頻率最高的實體了。

我們將這部分代碼封裝在process_documents函數中:

def process_documents():
    """Process downloaded documents using AlchemyAPI."""

    # 導入所需要的模塊,包括我們安裝的PyPDF2和AlchemyAPI。
    import PyPDF2
    import glob
    import time    
    from collections import Counter    
    from alchemyapi import AlchemyAPI

    alchemyapi = AlchemyAPI() # 初始化AlchemyAPI。
    file_list = glob.glob("pdfs/*.pdf") 
    # 通過`glob`模塊獲取我們下載的所有PDF文件的文件名。
    entities = {} 
    # 我們要使用`entities`字典來保存每個PDF文檔的分析結果。    # 下面的for循環將遍歷所有的PDF文件
    for pdf_file in file_list:

        # read in the PDF
        print("[*] Parsing %s" % pdf_file)

    # 初始化一個PyPDF2對象,用於保存從PDF文檔中提取的文本數據
        pdf_obj = PyPDF2.PdfFileReader(open(pdf_file, "rb"))

    # 創建一個空字符串,用於後續構建這個PDF的全部文本數據
        full_text = ""

        # 從每頁中提取文本數據
        for page in pdf_obj.pages:
            full_text += page.extractText()
    # 接下來我們使用Alchemy API進行實體抽取
        print("[*] Sending %d bytes to the Alchemy API" % len(full_text))
        # 調用AlchemyAPI,並明確我們提交的是文本數據(第一個參數)
        # 然後傳入需要分析的文本,第三個參數代表禁用情感分析功能,
        # 因爲本文中我們只關注頻率最��的實體。

        response = alchemyapi.entities('text', full_text, {'sentiment': 0})

        if response['status'] == 'OK':
            # 遍歷返回的全部實體數據。
            # Alchemy返回的每個實體中,都包含有`count`數據,
            # 我們要確保在`entities`字典中,將所有相同實體的count相加
            for entity in response['entities']:
                # add each entity to our master list
                if entity['text'] in entities:
                    entities[entity['text']] += int(entity['count'])
                else:
                    entities[entity['text']] = int(entity['count'])

            print("[*] Retrieved %d entities from %s" %
                  (len(entities), pdf_file))

        else:
            print("[!] Error receiving Alchemy response: %s" %
                  response['statusInfo'])

        time.sleep(1)

    # 上面的循環執行結束,我們可以統計最常見的實體,
    # 並把相關的結果打印出來了!
    entity_counter = Counter(entities)

    top_entities = entity_counter.most_common()

    # 接下來就開始打印本·拉登提到次數最多的實體吧!
    for top_entity in top_entities[0:10]:

        # most_common returns a tuple (entity,count)
        print("%s => %d" % (top_entity[0], top_entity[1]))

上面函數的最後,我們使用了Counter類來加載entities字典,並且很容易地就得出了最常見的實體。

快速執行腳本

最後執行腳本時,一定要注意:要把腳本放在alchemyapi_python這個文件夾裏。這是因爲AlchemyAPI SDK並沒有在Python的PATH上。

爲了讓大家少複製粘貼,我已經把相關的操作寫在一個bash腳本里。大家下載腳本後修改API KEY即可。

curl https://raw.githubusercontent.com/bingjin/funscripts/master/laden/bld.sh --output bld.sh
sh bld.sh

拉登信件分析腳本運行中

上圖就是正在執行的腳本。想不想看看最終的分析結果?

我直接告訴你們就太沒趣了,大家可以運行腳本自己看,等待的同時可以品嚐一杯咖啡。當然,劇透也是有的:伊斯蘭教先知穆罕默德居然才排第七!

你分析的結果是怎樣的,留言告訴大家本·拉登提到次數最多的三個實體吧!

結語

本文中僅使用了AlchemyAPI的實體提取功能,其他諸如關鍵詞分析、情感分析、圖像分析等功能都沒有涉及。大家可以在本文的基礎上,進一步發揮自己的想象力,看看還能從本·拉登的書架中得到什麼信息。


發佈了68 篇原創文章 · 獲贊 14 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章