數(shù)據(jù)是企業(yè)能夠擁有的最有價值的資產(chǎn)之一。它是數(shù)據(jù)科學和數(shù)據(jù)分析的核心:沒有數(shù)據(jù),它們都是過時的。積極收集數(shù)據(jù)的企業(yè)可能比不收集數(shù)據(jù)的公司具有競爭優(yōu)勢。有了足夠的數(shù)據(jù),組織可以更好地確定問題的原因并做出明智的決定。
在某些情況下,組織可能缺乏足夠的數(shù)據(jù)來得出必要的見解。例如,初創(chuàng)企業(yè)幾乎總是在沒有數(shù)據(jù)的情況下開始。與其抱怨他們的不足,更好的解決方案是使用數(shù)據(jù)采集技術來幫助構建定制數(shù)據(jù)庫。
這篇文章介紹了一種流行的數(shù)據(jù)采集技術,稱為網(wǎng)絡抓取。您可以使用 kurtispykes/web-scraping-real-estate-data GitHub 存儲庫中的代碼進行后續(xù)操作。
什么是數(shù)據(jù)采集?
Data acquisition (也稱為 DAQ )可能與技術人員記錄烤箱溫度一樣簡單。您可以將 DAQ 定義為對測量真實世界物理現(xiàn)象的信號進行采樣,并將生成的樣本轉換為計算機可以解釋的數(shù)字數(shù)值的過程。
在一個理想的世界里,我們將把所有的數(shù)據(jù)都交給我們,隨時可以使用。然而,世界遠非理想。數(shù)據(jù)采集技術之所以存在,是因為某些問題需要特定的數(shù)據(jù),而您在特定時間可能無法訪問這些數(shù)據(jù)。在進行任何數(shù)據(jù)分析之前,數(shù)據(jù)團隊必須有足夠的可用數(shù)據(jù)。一種獲取數(shù)據(jù)的技術是 web scraping 。
什么是網(wǎng)頁刮???
Web 抓取是一種流行的數(shù)據(jù)采集技術,在那些對大數(shù)據(jù)需求不斷增長的人中,它已成為討論的熱門話題。從本質上講,這是一個從互聯(lián)網(wǎng)中提取信息并將其格式化以便于在數(shù)據(jù)分析和數(shù)據(jù)科學管道中使用的過程。
在過去,網(wǎng)頁抓取是一個手動過程。這個過程既乏味又耗時,而且人類容易出錯。最常見的解決方案是自動化。 web 刮取的自動化使您能夠加快流程,同時節(jié)省資金并減少人為錯誤的可能性。
然而,網(wǎng)絡抓取也有其挑戰(zhàn)。
刮網(wǎng)的挑戰(zhàn)
除了知道如何編程和理解 HTML 之外,構建自己的 web scraper 還有很多挑戰(zhàn)。提前了解數(shù)據(jù)收集過程中可能遇到的各種障礙是有益的。以下是從 web 上抓取數(shù)據(jù)時面臨的一些最常見的挑戰(zhàn)。
robots.txt
抓取數(shù)據(jù)的權限通常保存在 robots.txt 文件中。此文件用于通知爬網(wǎng)程序可在網(wǎng)站上訪問的 URL 。它可以防止站點被請求過載。
在開始網(wǎng)頁抓取項目之前,首先要檢查的是目標網(wǎng)站是否允許網(wǎng)頁抓取。網(wǎng)站可以決定是否允許在其網(wǎng)站上使用刮片器進行刮片。
有些網(wǎng)站不允許自動抓取網(wǎng)頁,這通常是為了防止競爭對手獲得競爭優(yōu)勢,并從目標站點中耗盡服務器資源。它確實會影響網(wǎng)站的性能。
您可以通過將 /robots.txt 附加到域名來檢查網(wǎng)站的 robots.txt 文件。例如,檢查 Twitter 的 robots.txt 如下: www.twitter.com/robots.txt 。
結構變化
UI 和 UX 開發(fā)人員定期對網(wǎng)站進行添加、刪除和定期結構更改,以使其跟上最新進展。 Web scraper 依賴于構建 scraper 時網(wǎng)頁的代碼元素。因此,頻繁更改網(wǎng)站可能會導致數(shù)據(jù)丟失。隨時關注網(wǎng)頁的更改總是一個好主意。
此外,考慮到不同的網(wǎng)頁設計者在設計網(wǎng)頁時可能有不同的標準。這意味著,如果你計劃抓取多個網(wǎng)站,你可能需要構建多個抓取器,每個網(wǎng)站一個。
IP 攔截器,或被禁止
它有可能被禁止進入網(wǎng)站。如果你的網(wǎng)絡爬蟲向某個網(wǎng)站發(fā)送的請求數(shù)量非常高,那么你的 IP 地址可能會被禁止?;蛘撸W(wǎng)站可能會限制其訪問,以打破刮取過程。
在被認為是道德的和不道德的網(wǎng)絡抓取之間有一條細線:越過這條線很快就會導致 IP 屏蔽。
驗證碼
CAPTCHA (完全自動化的公共圖靈測試,以區(qū)分計算機和人類)正是它的名字所說的:區(qū)分人類和機器人。驗證碼所帶來的問題對于人類來說通常是合乎邏輯的、簡單明了的,但對于機器人來說,要完成同樣的任務是很有挑戰(zhàn)性的,這可以防止網(wǎng)站被垃圾郵件攻擊。
使用 CAPTCHA 抓取網(wǎng)站有一些合乎道德的解決方法。然而,這一討論超出了本文的范圍。
蜜罐陷阱
類似于你如何設置設備或外殼來捕捉入侵你家的害蟲,網(wǎng)站所有者設置蜜罐陷阱來捕捉刮器。這些陷阱通常是人類看不到的鏈接,但對網(wǎng)絡爬蟲來說是可見的。
其目的是獲取有關刮板的信息,例如其 IP 地址,以便他們阻止刮板訪問網(wǎng)站。
實時數(shù)據(jù)抓取
在某些情況下,您可能需要實時丟棄數(shù)據(jù)(例如,價格比較)。由于更改隨時可能發(fā)生,因此刮取器必須不斷監(jiān)控網(wǎng)站并刮取數(shù)據(jù)。實時獲取大量數(shù)據(jù)具有挑戰(zhàn)性。
Web 抓取最佳實踐
現(xiàn)在,您已經(jīng)意識到可能面臨的挑戰(zhàn),了解最佳實踐以確保您在道德上收集網(wǎng)絡數(shù)據(jù)非常重要。
尊重 robots.txt
在抓取 web 數(shù)據(jù)時,您將面臨的一個挑戰(zhàn)是遵守 robots.txt 的條款。遵循網(wǎng)站設置的關于 web 抓取可以抓取和不能抓取的指南是最佳做法。
如果一個網(wǎng)站不允許網(wǎng)絡抓取,那么抓取該網(wǎng)站是不道德的。最好找到另一個數(shù)據(jù)源,或者直接聯(lián)系網(wǎng)站所有者,討論解決方案。
善待服務器
Web 服務器只能承受這么多。超過 web 服務器的負載會導致服務器崩潰??紤]向主機服務器發(fā)出請求的可接受頻率。短時間內的幾個請求可能會導致服務器故障,進而破壞網(wǎng)站其他訪問者的用戶體驗。
保持請求之間的合理時間間隔,并考慮并行請求的數(shù)量。
非高峰時段刮水
了解一個網(wǎng)站什么時候可能會收到最多的流量,并避免在這段時間內進行抓取。您的目標是不妨礙其他訪問者的用戶體驗。當一個網(wǎng)站收到的流量減少時,你的道德責任是刮一刮。(這也對您有利,因為它顯著提高了刮板的速度。)
剪貼畫教程
Python 中的 Web 抓取通常涉及從零開始編寫幾個低級任務。然而, Scrapy ,一個開源的網(wǎng)絡爬行框架,默認情況下處理幾個常見的啟動需求。這意味著您可以專注于從目標網(wǎng)站中提取所需的數(shù)據(jù)。
為了展示 Scrapy 的威力,您開發(fā)了一個 spider ,這是一個 Scrapy 類,您可以在其中定義刮網(wǎng)器的行為。使用這個蜘蛛從 Boston Realty Advisors 網(wǎng)站上抓取所有列表。
在開始任何 web 刮取項目之前,檢查目標網(wǎng)站以進行刮取非常重要。在檢查網(wǎng)站時,我喜歡檢查的第一件事是頁面是靜態(tài)的還是由 JavaScript 生成的。
要打開開發(fā)人員工具箱,請按 F12 。在 Network 選項卡上,確保選中 Disable cache 。
要打開命令選項板,請按 CTRL + SHIFT + P ( Windows Linux )或 command + SHIFT-P ( Mac )。鍵入 Disable JavaScript ,然后按 Enter 鍵并重新加載目標網(wǎng)站。
空頁面告訴您目標網(wǎng)頁是使用 JavaScript 生成的。您無法通過解析開發(fā)者工具箱 Elements 選項卡中顯示的 HTML 元素來抓取頁面。在開發(fā)人員工具中重新啟用 JavaScript 并重新加載頁面。
還有更多要檢查的。
I 在開發(fā)人員工具箱中,選擇 XHR ( XMLHTTPRequest )選項卡。瀏覽發(fā)送到服務器的請求后,我注意到一些有趣的事情。有兩個請求稱為“ inventory ”,但在一個請求中,您可以訪問 JSON 中第一頁上的所有數(shù)據(jù)。
這一信息非常有用,因為這意味著您不必訪問波士頓房地產(chǎn)顧問網(wǎng)站上的主列表頁面即可獲取所需的數(shù)據(jù)。
現(xiàn)在你可以開始刮了。(我做了更多的檢查,以更好地理解如何模擬向服務器發(fā)出的請求,但這超出了本文的范圍。)
創(chuàng)建報廢項目
要設置 Scrapy 項目,首先安裝scrapy。我建議在 virtual environment 中執(zhí)行此步驟。
pip install scrapy
激活虛擬環(huán)境后,輸入以下命令:
scrapy startproject bradvisors
該命令創(chuàng)建一個名為bradvisors的 Scrapy 項目。 Scrapy 還會自動將一些文件添加到目錄中。
運行命令后,最終目錄結構如下所示:
. └── bradvisors ├── bradvisors │ ├── __init__.py │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── settings.py │ └── spiders │ └── __init__.py └── scrapy.cfg
到目前為止,您已經(jīng)檢查了網(wǎng)站的元素,并創(chuàng)建了 Scrapy 項目。
構建蜘蛛
蜘蛛模塊必須構建在bradvisors/bradvisors/spiders目錄中。我的蜘蛛腳本的名稱是bradvisors_spider.py,但您可以使用自定義名稱。
以下代碼從該網(wǎng)站中提取數(shù)據(jù)。代碼示例僅在items.py文件更新時成功運行。有關詳細信息,請參閱示例后的說明。
import json import scrapy from bradvisors.items import BradvisorsItem class BradvisorsSpider(scrapy.Spider): name = "bradvisors" start_urls = ["https://bradvisors.com/listings/"] url = "https://buildout.com/plugins/5339d012fdb9c122b1ab2f0ed59a55ac0327fd5f/inventory" headers = { 'authority': 'buildout.com', 'accept': 'application/json, text/javascript, */*; q=0.01', 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8', 'cache-control': 'no-cache', 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 'origin': 'https://buildout.com', 'pragma': 'no-cache', 'referer': 'https://buildout.com/plugins/5339d012fdb9c122b1ab2f0ed59a55ac0327fd5f/bradvisors.com/inventory/?pluginId=0&iframe=true&embedded=true&cacheSearch=true&=undefined', 'sec-ch-ua': '"Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36', 'x-newrelic-id': 'Vg4GU1RRGwIJUVJUAwY=', 'x-requested-with': 'XMLHttpRequest' } def parse(self, response): url = "https://buildout.com/plugins/5339d012fdb9c122b1ab2f0ed59a55ac0327fd5f/inventory" # There are 5 pages on the website for i in range(5): # Change the page number in the payload payload = f"utf8=%E2%9C%93&polygon_geojson=&lat_min=&lat_max=&lng_min=&lng_max=&mobile_lat_min= &mobile_lat_max=&mobile_lng_min=&mobile_lng_max=&page={str(i)}&map_display_limit=500&map_type=roadmap &custom_map_marker_url=%2F%2Fs3.amazonaws.com%2Fbuildout-production%2Fbrandings%2F7242%2Fprofile_photo %2Fsmall.png%3F1607371909&use_marker_clusterer=true&placesAutoComplete=&q%5Btype_use_offset_eq_any%5D%5B%5D= &q%5Bsale_or_lease_eq%5D=&q%5Bbuilding_size_sf_gteq%5D=&q%5Bbuilding_size_sf_lteq%5D=&q%5B listings_data_max_space_available_on_market_gteq%5D=&q%5Blistings_data_min_space_available_on_market_lteq %5D=&q%5Bproperty_research_property_year_built_gteq%5D=&q%5Bproperty_research_property_year_built_lteq %5D=&q%5Bproperty_use_id_eq_any%5D%5B%5D=&q%5Bcompany_office_id_eq_any%5D%5B%5D=&q%5Bs%5D%5B%5D=" # Crawl the data, given the payload yield scrapy.Request(method="POST", body=payload, url=url, headers=self.headers, callback=self.parse_api) def parse_api(self, response): # Response is json, use loads to convert it into Python dictionary data = json.loads(response.body) # Our item object defined in items.py item = BradvisorsItem() for listing in data["inventory"]: item["address"] = listing["address_one_line"] item["city"] = listing["city"] item["city_state"] = listing["city_state"] item["zip"] = listing["zip"] item["description"] = listing["description"] item["size_summary"] = listing["size_summary"] item["item_url"] = listing["show_link"] item["property_sub_type_name"] = listing["property_sub_type_name"] item["sale"] = listing["sale"] item["sublease"] = listing["sublease"] yield item
該代碼完成以下任務:
將刮刀的名稱定義為bradvisors。
定義隨請求傳遞的標頭。
指定parse方法是刮板運行時的自動回調。
定義parse方法,在該方法中,您遍歷要抓取的頁數(shù),將頁碼傳遞給有效負載,并生成該請求。這會在每次迭代時調用parse_api方法。
定義parse_api方法并將有效的 JSON 響應轉換為 Python 字典。
在items.py中定義BradvisorsItem類(下一個代碼示例)。
循環(huán)遍歷庫存中的所有列表并抓取特定元素。
# items.py import scrapy class BradvisorsItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() address = scrapy.Field() city = scrapy.Field() city_state = scrapy.Field() zip = scrapy.Field() description = scrapy.Field() size_summary = scrapy.Field() item_url = scrapy.Field() property_sub_type_name = scrapy.Field() sale = scrapy.Field()
接下來,必須執(zhí)行刮取以解析數(shù)據(jù)。
運行鏟運機
從命令行導航到項目的根目錄(在本例中為bradvisors)。運行以下命令:
scrapy crawl bradvisors -o data.csv
該命令將抓取 Boston Realty Advisors 網(wǎng)站,并將提取的數(shù)據(jù)保存在項目根目錄的data.csv文件中。
太好了,您現(xiàn)在已經(jīng)獲得了房地產(chǎn)數(shù)據(jù)!
接下來是什么?
隨著對大數(shù)據(jù)需求的增長,讓自己具備使用網(wǎng)絡抓取工具獲取數(shù)據(jù)的能力是一項非常有價值的技能。從互聯(lián)網(wǎng)上刪除數(shù)據(jù)可能會帶來一些挑戰(zhàn)。除了獲取所需的數(shù)據(jù)外,您的目標還應該是尊重網(wǎng)站,并以道德的方式收集網(wǎng)站。
-
NVIDIA
+關注
關注
14文章
4989瀏覽量
103077 -
AI
+關注
關注
87文章
30898瀏覽量
269134
發(fā)布評論請先 登錄
相關推薦
評論