一文告訴你,如何使用Python構建一個「谷歌搜索」系統|內附代碼

2020-12-11 AI科技大本營

來源 | hackernoon

編譯 | 武明利

責編 | Carol

在這篇文章中,我將向您展示如何使用Python構建自己的答案查找系統。基本上,這種自動化可以從圖片中找到多項選擇題的答案。

有一件事我們要清楚,在考試期間不可能在網際網路上搜索問題,但是當考官轉過身去的時候,我可以很快地拍一張照片。這是算法的第一部分。我得想辦法把這個問題從圖中提取出來。

似乎有很多服務可以提供文本提取工具,但是我需要某種API來解決此問題。最後,Google的VisionAPI正是我正在尋找的工具。很棒的事情是,每月前1000個API調用是免費的,這足以讓我測試和使用該API。

Vision AI

首先,創建Google雲帳戶,然後在服務中搜索Vision AI。使用VisionAI,您可以執行諸如為圖像分配標籤來組織圖像,獲取推薦的裁切頂點,檢測著名的風景或地方,提取文本等工作。

檢查文檔以啟用和設置API。配置後,您必須創建JSON文件,包含您下載到計算機的密鑰。

運行以下命令安裝客戶端庫:

pip install google-cloud-vision然後通過設置環境變量GOOGLE_APPLICATION_CREDENTIALS,為應用程式代碼提供身份驗證憑據。

import os, iofrom google.cloud import visionfrom google.cloud.vision import types# JSON file that contains your keyos.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'your_private_key.json'# Instantiates a clientclient = vision.ImageAnnotatorClientFILE_NAME = 'your_image_file.jpg'# Loads the image into memorywith io.open(os.path.join(FILE_NAME), 'rb') as image_file: content = image_file.readimage = vision.types.Image(content=content)# Performs text detection on the image fileresponse = client.text_detection(image=image)print(response)# Extract descriptiontexts = response.text_annotations[0]print(texts.description)在運行代碼時,您將看到JSON格式的響應,其中包括檢測到的文本的規範。但我們只需要純描述,所以我從響應中提取了這部分。

在Google上搜索問題

下一步是在Google上搜索問題部分來獲得一些信息。我使用正則表達式(regex)庫從描述(響應)中提取問題部分。然後我們必須將提取出的問題部分進行模糊化,以便能夠對其進行搜索。

import reimport urllib# If ending with question markif '?' in texts.description: question = re.search('([^?]+)', texts.description).group(1)# If ending with colonelif ':' in texts.description: question = re.search('([^:]+)', texts.description).group(1)# If ending with newlineelif '\n' in texts.description: question = re.search('([^\n]+)', texts.description).group(1)# Slugify the matchslugify_keyword = urllib.parse.quote_plus(question)print(slugify_keyword)

抓取的信息

我們將使用 BeautifulSoup 抓取前3個結果,以獲得關於問題的一些信息,因為答案可能位於其中之一。

另外,如果您想從Google的搜索列表中抓取特定的數據,不要使用inspect元素來查找元素的屬性,而是列印整個頁面來查看屬性,因為它與實際的屬性有所不同。

我們需要對搜索結果中的前3個連結進行抓取,但是這些連結確實被弄亂了,因此獲取用於抓取的乾淨連結很重要。

/url?q=https://en.wikipedia.org/wiki/IAU_definition_of_planet&sa=U&ved=2ahUKEwiSmtrEsaTnAhXtwsQBHduCCO4QFjAAegQIBBAB&usg=AOvVaw0HzMKrBxdHZj5u1Yq1t0en正如您所看到的,實際的連結位於q=和&sa之間。通過使用正則表達式Regex,我們可以獲得這個特定的欄位或有效的URL。

result_urls = def crawl_result_urls: req = Request('https://google.com/search?q=' + slugify_keyword, headers={'User-Agent': 'Mozilla/5.0'}) html = urlopen(req).read bs = BeautifulSoup(html, 'html.parser') results = bs.find_all('div', class_='ZINbbc') try: for result in results: link = result.find('a')['href'] # Checking if it is url (in case) if 'url' in link: result_urls.append(re.search('q=(.*)&sa', link).group(1)) except (AttributeError, IndexError) as e: pass在我們抓取這些URLs的內容之前,讓我向您展示使用Python的問答系統。

問答系統

這是算法的主要部分。從前3個結果中抓取信息後,程序應該通過迭代文檔來檢測答案。首先,我認為最好使用相似度算法來檢測與問題最相似的文檔,但是我不知道如何實現它。

經過幾個小時的研究,我在Medium上找到了一篇文章,用Python解釋了問答系統。它有易於使用的python軟體包能夠對您自己的私有數據實現一個QA系統。

讓我們先安裝這個包:

pip install cdqa我正在使用下面的示例代碼塊中包含的下載功能來手動下載經過預訓練的模型和數據:

import pandas as pdfrom ast import literal_evalfrom cdqa.utils.filters import filter_paragraphsfrom cdqa.utils.download import download_model, download_bnpp_datafrom cdqa.pipeline.cdqa_sklearn import QAPipeline# Download data and modelsdownload_bnpp_data(dir='./data/bnpp_newsroom_v1.1/')download_model(model='bert-squad_1.1', dir='./models')# Loading data and filtering / preprocessing the documentsdf = pd.read_csv('data/bnpp_newsroom_v1.1/bnpp_newsroom-v1.1.csv', converters={'paragraphs': literal_eval}) df = filter_paragraphs(df)# Loading QAPipeline with CPU version of BERT Reader pretrained on SQuAD 1.1 cdqa_pipeline = QAPipeline(reader='models/bert_qa.joblib')# Fitting the retriever to the list of documents in the dataframecdqa_pipeline.fit_retriever(df)# Sending a question to the pipeline and getting predictionquery = 'Since when does the Excellence Program of BNP Paribas exist?'prediction = cdqa_pipeline.predict(query)print('query: {}\n'.format(query))print('answer: {}\n'.format(prediction[0]))print('title: {}\n'.format(prediction[1]))print('paragraph: {}\n'.format(prediction[2]))它的輸出應該是這樣的:

它列印出確切的答案和包含答案的段落。

基本上,當從圖片中提取問題並將其發送到系統時,檢索器將從已抓取數據中選擇最有可能包含答案的文檔列表。如前所述,它計算問題與抓取數據中每個文檔之間的餘弦相似度。

在選擇了最可能的文檔後,系統將每個文檔分成幾個段落,並將問題一起發送給讀者,這基本上是一個預先訓練好的深度學習模型。所使用的模型是著名的NLP模型BERT的Pytorch 版本。

然後,讀者輸出在每個段落中找到的最可能的答案。在閱讀者之後,系統中的最後一層通過使用內部評分函數對答案進行比較,並根據分數輸出最有可能的答案,這將得到我們問題的答案。

下面是系統機制的模式。

你必須在特定的結構中設置數據幀(CSV),以便將其發送到 cdQA 管道。

但是實際上我使用PDF轉換器從PDF文件目錄創建了一個輸入數據框。因此,我要在pdf文件中保存每個結果的所有抓取數據。我們希望總共有3個pdf文件(也可以是1個或2個)。另外,我們需要命名這些pdf文件,這就是為什麼我抓取每個頁面的標題的原因。

def get_result_details(url): try: req = Request(url, headers={'User-Agent': 'Mozilla/5.0'}) html = urlopen(req).read bs = BeautifulSoup(html, 'html.parser') try: # Crawl any heading in result to name pdf file title = bs.find(re.compile('^h[1-6]$')).get_text.strip.replace('?', '').lower # Naming the pdf file filename = "/home/coderasha/autoans/pdfs/" + title + ".pdf" if not os.path.exists(os.path.dirname(filename)): try: os.makedirs(os.path.dirname(filename)) except OSError as exc: # Guard against race condition if exc.errno != errno.EEXIST: raise with open(filename, 'w') as f: # Crawl first 5 paragraphs for line in bs.find_all('p')[:5]: f.write(line.text + '\n') except AttributeError: pass except urllib.error.HTTPError: passdef find_answer: df = pdf_converter(directory_path='/home/coderasha/autoans/pdfs') cdqa_pipeline = QAPipeline(reader='models/bert_qa.joblib') cdqa_pipeline.fit_retriever(df) query = question + '?' prediction = cdqa_pipeline.predict(query) print('query: {}\n'.format(query)) print('answer: {}\n'.format(prediction[0])) print('title: {}\n'.format(prediction[1])) print('paragraph: {}\n'.format(prediction[2])) return prediction[0]我總結一下算法:它將從圖片中提取問題,在Google上搜索它,抓取前3個結果,從抓取的數據中創建3個pdf文件,最後使用問答系統找到答案

如果你想看看它是如何工作的,請檢查我做的一個可以從圖片中解決考試問題的機器人。

以下是完整的代碼:

import os, ioimport errnoimport urllibimport urllib.requestimport hashlibimport reimport requestsfrom time import sleepfrom google.cloud import visionfrom google.cloud.vision import typesfrom urllib.request import urlopen, Requestfrom bs4 import BeautifulSoupimport pandas as pdfrom ast import literal_evalfrom cdqa.utils.filters import filter_paragraphsfrom cdqa.utils.download import download_model, download_bnpp_datafrom cdqa.pipeline.cdqa_sklearn import QAPipelinefrom cdqa.utils.converters import pdf_converterresult_urls = os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'your_private_key.json'client = vision.ImageAnnotatorClientFILE_NAME = 'your_image_file.jpg'with io.open(os.path.join(FILE_NAME), 'rb') as image_file: content = image_file.readimage = vision.types.Image(content=content)response = client.text_detection(image=image)texts = response.text_annotations[0]# print(texts.description)if '?' in texts.description: question = re.search('([^?]+)', texts.description).group(1)elif ':' in texts.description: question = re.search('([^:]+)', texts.description).group(1)elif '\n' in texts.description: question = re.search('([^\n]+)', texts.description).group(1)slugify_keyword = urllib.parse.quote_plus(question)# print(slugify_keyword)def crawl_result_urls: req = Request('https://google.com/search?q=' + slugify_keyword, headers={'User-Agent': 'Mozilla/5.0'}) html = urlopen(req).read bs = BeautifulSoup(html, 'html.parser') results = bs.find_all('div', class_='ZINbbc') try: for result in results: link = result.find('a')['href'] print(link) if 'url' in link: result_urls.append(re.search('q=(.*)&sa', link).group(1)) except (AttributeError, IndexError) as e: passdef get_result_details(url): try: req = Request(url, headers={'User-Agent': 'Mozilla/5.0'}) html = urlopen(req).read bs = BeautifulSoup(html, 'html.parser') try: title = bs.find(re.compile('^h[1-6]$')).get_text.strip.replace('?', '').lower # Set your path to pdf directory filename = "/path/to/pdf_folder/" + title + ".pdf" if not os.path.exists(os.path.dirname(filename)): try: os.makedirs(os.path.dirname(filename)) except OSError as exc: if exc.errno != errno.EEXIST: raise with open(filename, 'w') as f: for line in bs.find_all('p')[:5]: f.write(line.text + '\n') except AttributeError: pass except urllib.error.HTTPError: passdef find_answer: # Set your path to pdf directory df = pdf_converter(directory_path='/path/to/pdf_folder/') cdqa_pipeline = QAPipeline(reader='models/bert_qa.joblib') cdqa_pipeline.fit_retriever(df) query = question + '?' prediction = cdqa_pipeline.predict(query) # print('query: {}\n'.format(query)) # print('answer: {}\n'.format(prediction[0])) # print('title: {}\n'.format(prediction[1])) # print('paragraph: {}\n'.format(prediction[2])) return prediction[0]crawl_result_urlsfor url in result_urls[:3]: get_result_details(url) sleep(5)answer = find_answerprint('Answer: ' + answer)有時它可能會混淆,但我認為總體來說是可以的。至少我可以用60%的正確答案通過考試。

歡迎開發者們在評論中告訴我你的看法!實際上,最好是一次遍歷所有問題,但我沒有足夠的時間來做這件事,所以只好下次繼續再做。

(*本文由AI科技大本營編譯,轉載請聯繫微信1092722531)

【end】

福利直達!CSDN技術公開課評選進行中直播進行中 | 技術馳援抗疫一線, Python 線上峰會全天精彩呈現分布式數據集訓營,從入門到精通,從理論到實踐,你不可錯過的精品課程!區塊鏈的陰暗面QQ 群文件緊急擴容;鍾南山團隊與阿里雲聯手推進新冠疫苗研發;PhpStorm 2019.3.3 發布願得一心人:矽谷億萬富豪們的婚姻怎樣?有人白首相守七十年

相關焦點

  • 如何使用 Python 構建一個「谷歌搜索」系統? | 內附代碼
    出品 | AI科技大本營(ID:rgznai100)在這篇文章中,我將向您展示如何使用Python構建自己的答案查找
  • 谷歌開放GNMT教程:如何使用TensorFlow構建自己的神經機器翻譯系統
    今天,我們很高興能夠發布最新的 TensorFlow 神經機器翻譯教程,幫助讀者全面了解 seq2seq 模型,並介紹如何從頭開始構建有競爭力的翻譯模型。該教程儘可能簡單地呈現該過程,教程首先介紹神經機器翻譯的背景知識,並講述構建 vanilla 系統的具體代碼。然後介紹注意力機制 [3, 4] 這一幫助 NMT 系統處理長句的重要工具。
  • 10個使用Python構建的著名網站
    閱讀更多關於Instagram如何在Instagram博客上使用Python的信息。2.谷歌谷歌是全球使用最廣泛的搜尋引擎,擁有超過75%的市場份額。雖然Spotify的網站是使用WordPress構建的,但Spotify應用程式是使用Python構建的。
  • 代碼詳解:Python虛擬環境的原理及使用
    · 只需要一個項目,無需在系統範圍內安裝軟體包,就能保持全局site-packages /目錄整潔。聽起來很方便,不是嗎?開始構建更複雜的項目並與其他人協作時,虛擬環境的重要性會凸顯出來。很多數據科學家也需要熟悉虛擬環境中與多語言相關的Conda環境。可按照先後次序來使用!
  • 使用 Python 構建圖片搜尋引擎
    當我們需要查詢時,我們可以使用像 Google 這樣的搜尋引擎來檢索最相關的答案。大多數查詢格式是基於文本的。但並不是大多數時候,文本對於找到相關的答案是非常有用的。例如,你想在網際網路上搜索一個產品,在這種情況下,是一件 t 恤,但你不知道它的名字。你怎麼能找到他們?你可以把那件襯衫的描述寫下來。使用描述的問題是你會得到各種各樣的產品。
  • 一文總結數據科學家常用的Python庫(下)
    一文總結數據科學家常用的Python庫(上)用於建模的Python庫我們已經到達了本文最受期待的部分 - 構建模型!這就是我們大多數人首先進入數據科學領域的原因,不是嗎?讓我們通過這三個Python庫探索模型構建。
  • 如何創建一個百分百懂你的產品推薦系統|深度教程(附代碼詳解)
    推薦系統如何提供幫助?簡單來說,推薦系統就是一個發現系統,該系統可通過分析數據向用戶提供推薦。不需要用戶去專門搜索,系統自動帶來推薦商品。這聽起來像是魔法。亞馬遜和Netflix幾十年前就開始使用這種魔法了。
  • 谷歌開源 Python Fire;一張圖讀懂 Python、R 的大數據應用等 | AI...
    開發者面對任意一個 Python 程序,僅需調用 Python Fire 即可把該程序轉為 CLI。Python Fire 已開源,用戶可通過`pip install fire`在 PyPI 進行下載,也可以去 GitHub 查看它的原始碼。
  • 好用的PYTHON IDE和代碼編輯器| TOP10推薦
    回顧一開始python的介紹,有一節直接就有一個定論:新手就入pycharm吧。正好搜索到一篇文章比較了十大 Python 編程 IDE(集成編程環境)《BEST PYTHON IDE AND CODE EDITORS | TOP 10》。正所謂磨刀不誤砍柴工,那就來過一遍吧(儘可能的漢化了如果翻譯的不夠專業,請指正):什麼是IDE你可以簡單理解是一個可以進行編寫、調試、釋放代碼的圖形化界面(軟體)。
  • 從零開始實現穿衣圖像分割完整教程(附python代碼演練)
    但我們也開發了一個巧妙的方法來避免這種問題。我們使用 OpenCV 提供的 GrubCut 算法。 該算法利用高斯混合模型分離前景和背景。 通過它可以幫助我們找到圖像中的人物。我們只實現了簡單的功能。 假設感興趣的人站在圖像的中間。python def cut(img): img = cv.resize(img,(224,224)) ¨K5K
  • 谷歌又一開源利器Atheris,Python代碼安全掃描工具
    近日谷歌開源了一款Python代碼安全漏洞掃描工具Atheris,希望開發者在漏洞被利用之前能夠用它來發現安全漏洞並修補漏洞。pythonAtheris介紹Atheris目前基於Apache-2.0 License開源在github上,Atheris是一個典型的漏洞檢查工具
  • 使用Python構建一個推薦系統需要幾步
    一種可能的解決方案是推薦網站內最暢銷的產品,即需求量大的產品。另一個可能的解決方案是推薦可以為企業帶來最大利潤的產品。如果我們可以根據客戶的需求和興趣向他們推薦一些商品,那麼它將對用戶的體驗產生積極影響並可能會導致用戶的頻繁訪問。因此,當今的企業正在通過研究用戶的過去行為來構建智能的推薦引擎。
  • 工具&方法 | 6行代碼教你用python做OLS回歸(內附CFPS實例)
    如果你還不會,那麼本文也會介紹一些 python 語法的基礎內容,方便大家理解。隨著數據資源的日漸豐富,學者們越來越多的需要接觸到大數據的處理,許多學者還是習慣使用 Stata 對數據進行處理,而 Stata 由於其自身的限制,在處理大數據集時要麼需要強勁的處理性能(昂貴的硬體成本),要麼需要等待較長時間(更加昂貴的時間成本)。
  • 我們現在如何使用谷歌搜索
    目前谷歌搜索不能使用了以前的辦法也失效了,訪問一些外網變得越來越困難,怎麼辦?我來支一招。一些網友保存了谷歌緩存伺服器地址,這些伺服器也都在境外,也確實能訪問到谷歌熟悉的搜索界面,注意網址如圖:這兩個網址不穩定,告訴大家另外一個辦法。看圖。
  • 如何自學成 Python 大神?這裡有些建議
    如果一個項目看起來太難了,那麼你可以採用下列解決方案之一:持續專注於這個問題,直到你能解決所有的子問題。先把問題放到一邊,做一些與原問題有關的簡單問題,然後再回來解決原來的問題。通過谷歌搜索解決方案是可以的,但是要儘量先獨立解決問題,自己編寫代碼,之後在去看別人是如何寫的。
  • 我們生活在「Python時代」
    當然,並不是python的所有組件都是由範羅蘇姆獨自一人開發的,它是一個開源項目,成千上萬的人都對Python的開發做出了貢獻。儘管python經過多年的發展已經有了很大的進步,但它的使用目的與當年相差不大。
  • 手把手教你用python搶票回家過年 !(附代碼)
    本文教大家用Python寫出搶火車票代碼以及實戰。首先看看如何快速查看剩餘火車票?當你想查詢一下火車票信息的時候,你還在上12306官網嗎?或是打開你手機裡的APP?下面讓我們來用Python寫一個命令行版的火車票查看器, 只要在命令行敲一行命令就能獲得你想要的火車票信息!如果你剛掌握了Python基礎,這將是個不錯的小練習。接口設計一個應用寫出來最終是要給人使用的,哪怕只是給你自己使用。所以,首先應該想想你希望怎麼使用它?
  • 如何到達谷歌搜索的頂部 [互動指南]-megalithant
    如何通過本地化SEO到達谷歌頂部 如果人們在谷歌中尋找本地商家,那麼你通常會在結果頂部看到一個 「地圖板塊」。 與大多數搜索結果不同,地圖板塊表會讓你進入 Google My Business 的列表,而不是其網站。
  • 谷歌高效開發的秘密:來自谷歌前員工的軟體開發工具指南
    Sourcegraph 的許多早期客戶,就是因為離職谷歌后想念原公司的代碼搜索功能而找到了我們。通過與客戶的緊密合作,我們了解到他們迫切需要填補的空白,進而去構建 Sourcegraph 的功能來滿足他們的需求。谷歌前員工正在探索如何在當前組織中使用新開發工具的模式。這一工作的靈感源自於他們使用谷歌開發工具而具備的經驗。當然,一些探索是成功的,也有些折戟沉沙。
  • 獨家 | 一文讀懂隨機森林的解釋和實現(附python代碼)
    雖然沒必要了解所有細節,但了解某個機器學習模型大致是如何工作的仍然有幫助。這使得我們可以在模型表現不佳時進行診斷,或者解釋模型是如何做決策的,這一點至關重要,尤其當我們想要說服別人相信我們的模型時。  在本文中,我們將介紹如何在Python中構建和使用隨機森林(Random Forest)。除了查看代碼之外,我們還將嘗試了解此模型的工作原理。