做者|LAKSHAY ARORA 編譯|Flin 來源|analyticsvidhyahtml
總覽
-
Web抓取是一種從網站提取數據的高效方法(取決於網站的規定)python
-
瞭解如何使用流行的BeautifulSoup庫在Python中執行網頁抓取web
-
咱們將介紹能夠抓取的不一樣類型的數據,例如文本和圖像正則表達式
介紹
咱們擁有的數據太少,沒法創建機器學習模型。咱們須要更多數據!後端
若是這句話聽起來很熟悉,那麼你並不孤單!但願得到更多數據來訓練咱們的機器學習模型是一個一直困擾人們的問題。咱們沒法在數據科學項目中得到能夠直接使用的Excel或.csv文件,對嗎?api
那麼,如何應對數據匱乏的問題呢?瀏覽器
實現此目的最有效,最簡單的方法之一就是經過網頁抓取。我我的發現網絡抓取是一種很是有用的技術,能夠從多個網站收集數據。現在,某些網站還爲你可能但願使用的許多不一樣類型的數據提供API,例如Tweets或LinkedIn帖子。網絡
可是有時你可能須要從不提供特定API的網站收集數據。這就是web抓取能力派上用場的地方。做爲數據科學家,你能夠編寫一個簡單的Python腳本並提取所需的數據。app
所以,在本文中,咱們將學習Web抓取的不一樣組件,而後直接研究Python,以瞭解如何使用流行且高效的BeautifulSoup庫執行Web抓取。框架
咱們還爲本文建立了一個免費課程:
- 使用Python進行Web爬網簡介。這種結構化的格式將幫助你更好地學習。
請注意,網頁抓取要遵照許多準則和規則。並不是每一個網站都容許用戶抓取內容,所以存在必定的法律限制。在嘗試執行此操做以前,請務必確保已閱讀網站的網站條款和條件。
目錄
-
3個流行的工具和庫,用於Python中的Web爬蟲
-
Web爬網的組件
- Crawl
- Parse and Transform
- Store
-
從網頁中爬取URL和電子郵件ID
-
爬取圖片
-
在頁面加載時抓取數據
3個流行的工具和庫,用於Python中的Web爬蟲
你將在Python中遇到多個用於Web抓取的庫和框架。如下是三種高效完成任務的熱門工具:
BeautifulSoup
-
BeautifulSoup是Python中一個了不得的解析庫,可用於從HTML和XML文檔進行Web抓取。
-
BeautifulSoup會自動檢測編碼並優雅地處理HTML文檔,即便帶有特殊字符也是如此。咱們能夠瀏覽已解析的文檔並找到所需的內容,這使得從網頁中提取數據變得快捷而輕鬆。在本文中,咱們將詳細學習如何使用Beautiful Soup構建web Scraper
Scrapy
- Scrapy是用於大規模Web抓取的Python框架。它爲你提供了從網站中高效提取數據,根據須要進行處理並以你喜歡的結構和格式存儲數據所需的全部工具。你能夠在這裏閱讀更多有關Scrapy的信息。
Selenium
- Selenium是另外一個使瀏覽器自動化的流行工具。它主要用於行業中的測試,但也很是方便進行網頁抓取。看看這篇很棒的文章,以瞭解更多有關使用Selenium進行Web抓取的工做方式的信息。
Web爬網的組件
這是構成網頁抓取的三個主要組成部分的出色說明:
讓咱們詳細瞭解這些組件。咱們將經過goibibo網站抓取酒店的詳細信息,例如酒店名稱和每間客房的價格,以實現此目的:
注意:請始終遵循目標網站的robots.txt文件,該文件也稱爲漫遊器排除協議。這能夠告訴網絡漫遊器不要抓取哪些頁面。
所以,咱們被容許從目標URL中抓取數據。咱們很高興去寫咱們的網絡機器人的腳本。讓咱們開始!
第1步:Crawl(抓取)
Web抓取的第一步是導航到目標網站並下載網頁的源代碼。咱們將使用請求庫來執行此操做。http.client和urlib2是另外兩個用於發出請求和下載源代碼的庫。
- http.client:https://docs.python.org/3/library/http.client.html#module-http.client
- urlib2:https://docs.python.org/2/library/urllib2.html
下載了網頁的源代碼後,咱們須要過濾所需的內容:
""" Web Scraping - Beautiful Soup """ # importing required libraries import requests from bs4 import BeautifulSoup import pandas as pd # target URL to scrap url = "https://www.goibibo.com/hotels/hotels-in-shimla-ct/" # headers headers = { 'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" } # send request to download the data response = requests.request("GET", url, headers=headers) # parse the downloaded data data = BeautifulSoup(response.text, 'html.parser') print(data)
步驟2:Parse and Transform(解析和轉換)
Web抓取的下一步是將這些數據解析爲HTML解析器,爲此,咱們將使用BeautifulSoup庫。如今,若是你已經注意到咱們的目標網頁,則與大多數網頁同樣,特定酒店的詳細信息也位於不一樣的卡片上。
所以,下一步將是從完整的源代碼中過濾卡片數據。接下來,咱們將選擇該卡片,而後單擊「Inspect Element」選項以獲取該特定卡的源代碼。你將得到以下內容:
全部卡的類名都相同,咱們能夠經過傳遞標籤名稱和屬性(如<class>標籤)來得到這些卡的列表,其名稱以下所示:
# find all the sections with specifiedd class name cards_data = data.find_all('div', attrs={'class', 'width100 fl htlListSeo hotel-tile-srp-container hotel-tile-srp-container-template new-htl-design-tile-main-block'}) # total number of cards print('Total Number of Cards Found : ', len(cards_data)) # source code of hotel cards for card in cards_data: print(card)
咱們從網頁的完整源代碼中過濾出了卡數據,此處的每張卡都包含有關單獨酒店的信息。僅選擇酒店名稱,執行「Inspect Element」步驟,並對房間價格執行相同操做:
如今,對於每張卡,咱們必須找到上面的酒店名稱,這些名稱只能從<p>標籤中提取。這是由於每張卡和房價只有一個 < p > 標籤和 < class > 標籤和類名:
# extract the hotel name and price per room for card in cards_data: # get the hotel name hotel_name = card.find('p') # get the room price room_price = card.find('li', attrs={'class': 'htl-tile-discount-prc'}) print(hotel_name.text, room_price.text)
步驟3:Store(儲存數據)
最後一步是將提取的數據存儲在CSV文件中。在這裏,對於每張卡,咱們將提取酒店名稱和價格並將其存儲在Python字典中。而後,咱們最終將其添加到列表中。
接下來,讓咱們繼續將此列表轉換爲Pandas數據框,由於它容許咱們將數據框轉換爲CSV或JSON文件:
# create a list to store the data scraped_data = [] for card in cards_data: # initialize the dictionary card_details = {} # get the hotel name hotel_name = card.find('p') # get the room price room_price = card.find('li', attrs={'class': 'htl-tile-discount-prc'}) # add data to the dictionary card_details['hotel_name'] = hotel_name.text card_details['room_price'] = room_price.text # append the scraped data to the list scraped_data.append(card_details) # create a data frame from the list of dictionaries dataFrame = pd.DataFrame.from_dict(scraped_data) # save the scraped data as CSV file dataFrame.to_csv('hotels_data.csv', index=False)
恭喜!咱們已經成功建立了一個基本的網頁抓取工具。我但願你嘗試這些步驟,並嘗試獲取更多數據,例如酒店的等級和地址。如今,讓咱們看看如何執行一些常見任務,例如在頁面加載時抓取URL,電子郵件ID,圖像和抓取數據。
從網頁中抓取URL和電子郵件ID
咱們嘗試使用網絡抓取功能抓取的兩個最多見的功能是網站URL和電子郵件ID。我敢確定你曾經參與過須要大量提取電子郵件ID的項目或挑戰。所以,讓咱們看看如何在Python中抓取這些內容。
使用Web瀏覽器的控制檯
假設咱們要跟蹤咱們的Instagram關注者,並想知道取消關注咱們賬戶的人的用戶名。首先,登陸到你的Instagram賬戶,而後單擊關注者以查看列表:
-
一直向下滾動,以便將全部用戶名都加載到瀏覽器內存中的後臺
-
右鍵單擊瀏覽器窗口,而後單擊「檢查元素」
-
在控制檯窗口中,鍵入如下命令:
urls = $$(‘a’); for (url in urls) console.log ( urls[url].href);
僅需一行代碼,咱們就能夠找到該特定頁面上存在的全部URL:
-
接下來,將此列表保存在兩個不一樣的時間戳中,一個簡單的Python程序將使你知道二者之間的區別。咱們將可以知道取消了咱們的賬戶的用戶名!
-
咱們可使用多種方法來簡化此任務。主要思想是,只需一行代碼,咱們就能夠一次性得到全部URL。
使用Chrome擴展程序電子郵件提取器
電子郵件提取器是一個Chrome插件,可捕獲咱們當前正在瀏覽的頁面上顯示的電子郵件ID
它甚至容許咱們下載CSV或文本文件中的電子郵件ID列表:
BeautifulSoup和正則表達式
僅當咱們只想從一頁抓取數據時,以上解決方案纔有效。可是,若是咱們但願對多個網頁執行相同的步驟怎麼辦?
有許多網站能夠經過收費爲咱們作到這一點。但這裏有個好消息——咱們還可使用Python編寫本身的Web爬蟲!讓咱們在下面的實時編碼窗口中查看操做方法。
在Python中爬取圖片
在本節中,咱們將從同一個Goibibibo網頁抓取全部圖片。第一步是導航到目標網站並下載源代碼。接下來,咱們將使用 < img > 標籤查找全部圖像:
""" Web Scraping - Scrap Images """ # importing required libraries import requests from bs4 import BeautifulSoup # target URL url = "https://www.goibibo.com/hotels/hotels-in-shimla-ct/" headers = { 'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" } response = requests.request("GET", url, headers=headers) data = BeautifulSoup(response.text, 'html.parser') # find all with the image tag images = data.find_all('img', src=True) print('Number of Images: ', len(images)) for image in images: print(image)
從全部圖像標籤中,僅選擇src部分。另外,請注意,酒店圖片以jpg格式提供。所以,咱們將僅選擇那些:
# select src tag image_src = [x['src'] for x in images] # select only jp format images image_src = [x for x in image_src if x.endswith('.jpg')] for image in image_src: print(image)
如今咱們有了圖像URL的列表,咱們要作的就是請求圖像內容並將其寫入文件中。確保打開文件「 wb」(寫二進制文件)形式
image_count = 1 for image in image_src: with open('image_'+str(image_count)+'.jpg', 'wb') as f: res = requests.get(image) f.write(res.content) image_count = image_count+1
你還能夠按頁碼更新初始頁面URL,並反覆請求它們以收集大量數據。
在頁面加載時抓取數據
讓咱們看一下Steam社區Grant Theft Auto V Reviews的網頁。你會注意到網頁的完整內容不會一口氣加載。
咱們須要向下滾動以在網頁上加載更多內容。這是網站後端開發人員使用的一種稱爲「延遲加載」的優化技術。
可是對咱們來講,問題是,當咱們嘗試從該頁面抓取數據時,咱們只會獲得該頁面的有限內容:
一些網站還建立了「加載更多」按鈕,而不是無休止的滾動想法。僅當你單擊該按鈕時,它將加載更多內容。內容有限的問題仍然存在。所以,讓咱們看看如何抓取這些網頁。
導航到目標URL並打開「檢查元素網絡」窗口。接下來,點擊從新加載按鈕,它將爲你記錄網絡,如圖像加載,API請求,POST請求等的順序。
清除當前記錄並向下滾動。你會注意到,向下滾動時,該網頁正在發送更多數據的請求:
進一步滾動,你將看到網站發出請求的方式。查看如下URL——僅某些參數值正在更改,你能夠經過簡單的Python代碼輕鬆生成這些URL:
你須要按照相同的步驟來抓取和存儲數據,方法是將請求一頁一頁地發送到每一個頁面。
尾註
這是使用功能強大的BeautifulSoup庫對Python中的網絡抓取進行的簡單且對初學者友好的介紹。老實說,當我正在尋找一個新項目或須要一個現有項目的信息時,我發現網絡抓取很是有用。
注意:若是你想以更結構化的形式學習本教程,咱們有一個免費課程,咱們將教授網絡抓取BeatifulSoup。你能夠在此處查看—— 使用Python進行Web爬網簡介。
如前所述,還有其餘一些庫可用於執行Web抓取。我很想聽聽你更喜歡的庫的想法(即便你使用R語言!),以及你對該主題的經驗。在下面的評論部分中告訴我,咱們將與你聯繫!
原文連接:https://www.analyticsvidhya.com/blog/2019/10/web-scraping-hands-on-introduction-python/
歡迎關注磐創AI博客站: http://panchuang.net/
sklearn機器學習中文官方文檔: http://sklearn123.com/
歡迎關注磐創博客資源彙總站: http://docs.panchuang.net/