用Python進行Web爬取數據

介紹

我們擁有的數據太少,無法建立機器學習模型。我們需要更多數據!

如果這句話聽起來很熟悉,那麼你並不孤單!希望獲得更多數據來訓練我們的機器學習模型是一個一直困擾人們的問題。我們無法在數據科學項目中獲得可以直接使用的Excel或.csv文件,對嗎?

那麼,如何應對數據匱乏的問題呢?

實現此目的最有效,最簡單的方法之一就是通過網頁抓取。我個人發現網絡抓取是一種非常有用的技術,可以從多個網站收集數據。如今,某些網站還為你可能希望使用的許多不同類型的數據提供API,例如Tweets或LinkedIn帖子。

用Python進行Web爬取數據

但是有時你可能需要從不提供特定API的網站收集數據。這就是web抓取能力派上用場的地方。作為數據科學家,你可以編寫一個簡單的Python腳本並提取所需的數據。

因此,在本文中,我們將學習Web抓取的不同組件,然後直接研究Python,以瞭解如何使用流行且高效的BeautifulSoup庫執行Web抓取。

請注意,網頁抓取要遵守許多準則和規則。並非每個網站都允許用戶抓取內容,因此存在一定的法律限制。在嘗試執行此操作之前,請務必確保已閱讀網站的網站條款和條件。

目錄

  1. 3個流行的工具和庫,用於Python中的Web爬蟲
  2. Web爬網的組件 Crawl Parse and Transform Store
  3. 從網頁中爬取URL和電子郵件ID
  4. 爬取圖片
  5. 在頁面加載時抓取數據

3個流行的工具和庫,用於Python中的Web爬蟲

你將在Python中遇到多個用於Web抓取的庫和框架。以下是三種高效完成任務的熱門工具:

BeautifulSoup

  • BeautifulSoup是Python中一個了不起的解析庫,可用於從HTML和XML文檔進行Web抓取。
  • BeautifulSoup會自動檢測編碼並優雅地處理HTML文檔,即使帶有特殊字符也是如此。我們可以瀏覽已解析的文檔並找到所需的內容,這使得從網頁中提取數據變得快捷而輕鬆。在本文中,我們將詳細學習如何使用Beautiful Soup構建web Scraper

Scrapy

  • Scrapy是用於大規模Web抓取的Python框架。它為你提供了從網站中高效提取數據,根據需要進行處理並以你喜歡的結構和格式存儲數據所需的所有工具。你可以在這裡閱讀更多有關Scrapy的信息。 https://www.analyticsvidhya.com/blog/2017/07/web-scraping-in-python-using-scrapy

Selenium

  • Selenium是另一個使瀏覽器自動化的流行工具。它主要用於行業中的測試,但也非常方便進行網頁抓取。看看這篇很棒的文章,以瞭解更多有關使用Selenium進行Web抓取的工作方式的信息。 https://www.analyticsvidhya.com/blog/2019/05/scraping-classifying-youtube-video-data-python-selenium

Web爬網的組件

這是構成網頁抓取的三個主要組成部分的出色說明:

用Python進行Web爬取數據

讓我們詳細瞭解這些組件。我們將通過goibibo網站抓取酒店的詳細信息,例如酒店名稱和每間客房的價格,以實現此目的:

用Python進行Web爬取數據

注意:請始終遵循目標網站的robots.txt文件,該文件也稱為漫遊器排除協議。這可以告訴網絡漫遊器不要抓取哪些頁面。

  • https://www.goibibo.com/robots.txt
用Python進行Web爬取數據

因此,我們被允許從目標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

下載了網頁的源代碼後,我們需要過濾所需的內容:

<code>

""" Web Scraping - Beautiful Soup """

import

requests

from

bs4

import

BeautifulSoup

import

pandas

as

pd 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'

) print(data) /<code>

步驟2:Parse and Transform(解析和轉換)

Web抓取的下一步是將這些數據解析為HTML解析器,為此,我們將使用BeautifulSoup庫。現在,如果你已經注意到我們的目標網頁,則與大多數網頁一樣,特定酒店的詳細信息也位於不同的卡片上。

因此,下一步將是從完整的源代碼中過濾卡片數據。接下來,我們將選擇該卡片,然後單擊“Inspect Element”選項以獲取該特定卡的源代碼。你將獲得如下內容:

用Python進行Web爬取數據

所有卡的類名都相同,我們可以通過傳遞標籤名稱和屬性(如標籤)來獲得這些卡的列表,其名稱如下所示:

<code> 
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'

})

print

(

'Total Number of Cards Found : '

, len(cards_data))

for

card

in

cards_data:

print

(card) /<code>
用Python進行Web爬取數據

我們從網頁的完整源代碼中過濾出了卡數據,此處的每張卡都包含有關單獨酒店的信息。僅選擇酒店名稱,執行“Inspect Element”步驟,並對房間價格執行相同操作:

用Python進行Web爬取數據

現在,對於每張卡,我們必須找到上面的酒店名稱,這些名稱只能從

標籤中提取。這是因為每張卡和房價只有一個 < p > 標籤和 < class > 標籤和類名:

<code> 

for

card

in

cards_data: hotel_name = card.find(

'p'

) room_price = card.find(

'li'

, attrs={

'class'

:

'htl-tile-discount-prc'

})

print

(hotel_name.text, room_price.text) /<code>
用Python進行Web爬取數據

步驟3:Store(儲存數據)

最後一步是將提取的數據存儲在CSV文件中。在這裡,對於每張卡,我們將提取酒店名稱和價格並將其存儲在Python字典中。然後,我們最終將其添加到列表中。

接下來,讓我們繼續將此列表轉換為Pandas數據框,因為它允許我們將數據框轉換為CSV或JSON文件:

<code> 
scraped_data = []

for

card in cards_data: card_details = {} hotel_name = card.find(

'p'

) room_price = card.find(

'li'

, attrs={

'class'

:

'htl-tile-discount-prc'

}) card_details[

'hotel_name'

] = hotel_name.text card_details[

'room_price'

] = room_price.text scraped_data.append(card_details) dataFrame = pd.DataFrame.from_dict(scraped_data) dataFrame.to_csv(

'hotels_data.csv'

,

index

=False) /<code>
用Python進行Web爬取數據

恭喜!我們已經成功創建了一個基本的網頁抓取工具。我希望你嘗試這些步驟,並嘗試獲取更多數據,例如酒店的等級和地址。現在,讓我們看看如何執行一些常見任務,例如在頁面加載時抓取URL,電子郵件ID,圖像和抓取數據。

從網頁中抓取URL和電子郵件ID

我們嘗試使用網絡抓取功能抓取的兩個最常見的功能是網站URL和電子郵件ID。我敢肯定你曾經參與過需要大量提取電子郵件ID的項目或挑戰。因此,讓我們看看如何在Python中抓取這些內容。

使用Web瀏覽器的控制檯

假設我們要跟蹤我們的Instagram關注者,並想知道取消關注我們帳戶的人的用戶名。首先,登錄到你的Instagram帳戶,然後單擊關注者以查看列表:

用Python進行Web爬取數據

  • 一直向下滾動,以便將所有用戶名都加載到瀏覽器內存中的後臺
  • 右鍵單擊瀏覽器窗口,然後單擊“檢查元素”
  • 在控制檯窗口中,鍵入以下命令:
<code>

urls

= $$(‘a’) /<code>
用Python進行Web爬取數據

僅需一行代碼,我們就可以找到該特定頁面上存在的所有URL:

用Python進行Web爬取數據

  • 接下來,將此列表保存在兩個不同的時間戳中,一個簡單的Python程序將使你知道兩者之間的區別。我們將能夠知道取消了我們的帳戶的用戶名!
  • 我們可以使用多種方法來簡化此任務。主要思想是,只需一行代碼,我們就可以一次性獲得所有URL。

使用Chrome擴展程序電子郵件提取器

電子郵件提取器是一個Chrome插件,可捕獲我們當前正在瀏覽的頁面上顯示的電子郵件ID

它甚至允許我們下載CSV或文本文件中的電子郵件ID列表:

用Python進行Web爬取數據

BeautifulSoup和正則表達式

僅當我們只想從一頁抓取數據時,以上解決方案才有效。但是,如果我們希望對多個網頁執行相同的步驟怎麼辦?

有許多網站可以通過收費為我們做到這一點。但這裡有個好消息——我們還可以使用Python編寫自己的Web爬蟲!讓我們在下面的實時編碼窗口中查看操作方法。

  • https://id.analyticsvidhya.com/auth/login/?next=https://www.analyticsvidhya.com/blog/2019/10/web-scraping-hands-on-introduction-python

在Python中爬取圖片

在本節中,我們將從同一個Goibibibo網頁抓取所有圖片。第一步是導航到目標網站並下載源代碼。接下來,我們將使用 < img > 標籤查找所有圖像:

<code>

""" Web Scraping - Scrap Images """

import

requests

from

bs4

import

BeautifulSoup 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'

) images = data.find_all(

'img'

, class="lazy" data-original=

True

) print(

'Number of Images: '

, len(images))

for

image

in

images: print(image) /<code>
用Python進行Web爬取數據

從所有圖像標籤中,僅選擇src部分。另外,請注意,酒店圖片以jpg格式提供。因此,我們將僅選擇那些:

<code># 

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) /<code>
用Python進行Web爬取數據

現在我們有了圖像URL的列表,我們要做的就是請求圖像內容並將其寫入文件中。確保打開文件“ wb”(寫二進制文件)形式

<code>
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

/<code>
用Python進行Web爬取數據

你還可以按頁碼更新初始頁面URL,並反覆請求它們以收集大量數據。

在頁面加載時抓取數據

讓我們看一下Steam社區Grant Theft Auto V Reviews的網頁。你會注意到網頁的完整內容不會一口氣加載。

  • https://steamcommunity.com/app/271590/reviews/?browsefilter=toprated&snr=1_5_100010_

我們需要向下滾動以在網頁上加載更多內容。這是網站後端開發人員使用的一種稱為“延遲加載”的優化技術。

但是對我們來說,問題是,當我們嘗試從該頁面抓取數據時,我們只會得到該頁面的有限內容:

一些網站還創建了“加載更多”按鈕,而不是無休止的滾動想法。僅當你單擊該按鈕時,它將加載更多內容。內容有限的問題仍然存在。因此,讓我們看看如何抓取這些網頁。

導航到目標URL並打開“檢查元素網絡”窗口。接下來,點擊重新加載按鈕,它將為你記錄網絡,如圖像加載,API請求,POST請求等的順序。

清除當前記錄並向下滾動。你會注意到,向下滾動時,該網頁正在發送更多數據的請求:

用Python進行Web爬取數據

進一步滾動,你將看到網站發出請求的方式。查看以下URL——僅某些參數值正在更改,你可以通過簡單的Python代碼輕鬆生成這些URL:

用Python進行Web爬取數據

你需要按照相同的步驟來抓取和存儲數據,方法是將請求一頁一頁地發送到每個頁面。

尾註

這是使用功能強大的BeautifulSoup庫對Python中的網絡抓取進行的簡單且對初學者友好的介紹。老實說,當我正在尋找一個新項目或需要一個現有項目的信息時,我發現網絡抓取非常有用。

注意:如果你想以更結構化的形式學習本教程,我們有一個免費課程,我們將教授網絡抓取BeatifulSoup。你可以在此處查看—— 使用Python進行Web爬網簡介。

  • https://courses.analyticsvidhya.com/courses/introduction-to-web-scraping

如前所述,還有其他一些庫可用於執行Web抓取。我很想聽聽你更喜歡的庫的想法(即使你使用R語言!),以及你對該主題的經驗。在下面的評論部分中告訴我,我們將與你聯繫!


分享到:


相關文章: