elasticsearch入門系列">elasticsearch入門系列
720
2022-05-28
本期爬蟲系列主要講解爬蟲采集完成數據之后,我們應該怎么存儲,以及用什么樣的方式存儲數據。
雖然在命令行里顯示結果很有意思,但是隨著數據不斷增多,并且需要對數據分析時,將數據打印到命令行就不是辦法了。為了可以遠程使用大部分網絡爬蟲,你還需要把采集到的數據存儲起來。
本篇文章介紹的數據存儲方式,絕大多數應用程序都適用。如果你準備創建一個網站的后端服務或者創建自己的 API,那么可能需要把數據寫入數據庫。如果你需要一個快速簡單的方法收集網上的文檔,然后保存到你的硬盤里,那么可能需要創建一個文件流(file stream)來實現。
存儲媒體文件
存儲媒體文件主要有兩種方式:只獲取文件 URL 鏈接,或者直接把源文件下載下來。你可以通過媒體文件所在的 URL 鏈接直接引用它。這樣做的優點如下:
爬蟲運行得更快,耗費得流量更少,因為只要鏈接,不需要下載文件;
可以節省很多存儲空間,因為只需要存儲 URL 鏈接就可以了;
存儲 URL 的代碼更容易編寫,也不需要文件下載代碼;
不下載文件能夠降低目標服務器的負載。
保存媒體文件存在的缺點:
這些內嵌在你網站或應用中的外站 URL 鏈接稱為盜鏈(hotlinking),使用盜鏈可能讓你麻煩不斷,每個網站都會實施防盜鏈措施;
因為你的鏈接放在別人的服務器上,所以你的應用就跟著別人的節奏運行了;
盜鏈是很容易改變的。如果你把盜鏈圖片放在博客上,要是被對方服務器發現,就可能被惡搞。如果你把 URL 鏈接存儲起來準備以后再使用,可能用的時候鏈接已經失效了,或者變成了完全無關的內容;
現實中的瀏覽器不僅會請求 HTML 頁面并切換頁面,它們也會下載訪問頁面上所有的資源。下載文件會讓你的爬蟲看起來更像人在瀏覽網站,這樣做反而有好處。
如果你還在猶豫究竟是存儲文件,還只是存儲文件的 URL 鏈接,可以想想這些文件是要多次使用還是放進數據庫之后就只等著“落灰”,再也不會被打開。如果答案是后者,那么最好還是只存儲這些文件的 URL 吧。如果答案是前者,那就繼續往下看。
import requests from utils import connection_util class SaveData(object): def __init__(self): self._target_url = 'https://www.pdflibr.com' self._init_connection = connection_util.ProcessConnection() def save_image(self): # 連接目標網站,獲取內容 get_content = self._init_connection.init_connection(self._target_url) if get_content: imageLocation = get_content.find("img", {"alt": "IP to Location"})["data-src"] real_path = self._target_url + imageLocation r = requests.get(real_path) with open("ip_location.png", 'wb') as f: f.write(r.content) if __name__ == "__main__": SaveData().save_image()
這段程序從IP 查詢 - 爬蟲識別下載一張圖片,然后保存在運行程序的文件夾里。
如果你只需要下載一個文件,而且知道如何獲取它,以及它的文件類型,這么做就可以了。但是大多數爬蟲一天只下載一個文件。下面的程序會把IP 查詢 - 爬蟲識別上所有 src 屬性的文件都下載下來:
import os.path from urllib.request import urlretrieve from utils import connection_util class GetAllSrc(object): def __init__(self): self._init_download_dir = 'downloaded' self._baseUrl = 'https://www.pdflibr.com/ip' self._init_connection = connection_util.ProcessConnection() def get_absolute_url(self, baseUrl, source): if source.startswith("https://image."): url = "https://" + source[14:] elif source.startswith("https://"): url = source elif source.startswith("www."): url = "https://" + source[4:] else: url = source if baseUrl not in url: return None return url def get_download_path(self, baseUrl, absoluteUrl, download_dir): path = absoluteUrl.replace("www.", "") path = path.replace(baseUrl, "") path = download_dir + path directory = os.path.dirname(path) if not os.path.exists(directory): os.makedirs(directory) return path def download_main(self): get_content = self._init_connection.init_connection(self._baseUrl) if get_content: download_list = get_content.findAll(src=True) for download in download_list: file_url = self.get_absolute_url(self._baseUrl, download["src"]) if file_url is not None: print(file_url) urlretrieve(file_url, self.get_download_path(self._baseUrl, file_url, self._init_download_dir)) if __name__ == '__main__': GetAllSrc().download_main()
運行以上代碼需要注意:
這個程序會把頁面上所有的文件都下載到你硬盤里,可能會包含一些 bash 腳本,.exe 文件,設置可能是惡意軟件(malmare)。
這個程序首先選擇頁面上所有帶 src 屬性的標簽,然后對 URL 鏈接進行清理和標準化,獲得了文件的絕對路徑(而且去掉了外鏈),最后每個文件都會下載到程序所在的 downloaded 文件里。
這里使用 Python 的 os 模塊用來獲取每個下載文件的目標文件夾,建立完整的路徑。os 模塊是 Python 與操作系統交互的接口,它可以操作文件路徑,創建目錄,獲取運行進程和環境變量的信息,以及其他系統相關操作。
文章源代碼托管于 Github:爬蟲系列:存儲媒體文件
5G媒體 Python 爬蟲 網站
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。