推薦 :手把手教你用Python進行Web抓取(附代碼)

2021-02-24 數據分析

作者:Kerry Parker ;翻譯:田曉寧;校對:丁楠雅;

本文約2900字,建議閱讀10分鐘

本教程以在Fast Track上收集百強公司的數據為例,教你抓取網頁信息。

作為一名數據科學家,我在工作中所做的第一件事就是網絡數據採集。使用代碼從網站收集數據,當時對我來說是一個完全陌生的概念,但它是最合理、最容易獲取的數據來源之一。經過幾次嘗試,網絡抓取已經成為我的第二天性,也是我幾乎每天使用的技能之一。

在本教程中,我將介紹一個簡單的例子,說明如何抓取一個網站,我將從Fast Track上收集2018年百強公司的數據:

Fast Track:

http://www.fasttrack.co.uk/

使用網絡爬蟲將此過程自動化,避免了手工收集數據,節省了時間,還可以讓所有數據都放在一個結構化文件中。

用Python實現一個簡單的網絡爬蟲的快速示例,您可以在GitHub上找到本教程中所介紹的完整代碼。

GitHub連結:

https://github.com/kaparker/tutorials/blob/master/pythonscraper/websitescrapefasttrack.py

以下是本文使用Python進行網頁抓取的簡短教程概述:

連接到網頁

使用BeautifulSoup解析html

循環通過soup對象找到元素

執行一些簡單的數據清理

將數據寫入csv

準備開始

在開始使用任何Python應用程式之前,要問的第一個問題是:我需要哪些庫?

對於web抓取,有一些不同的庫需要考慮,包括:

Beautiful Soup

Requests

Scrapy

Selenium

在本例中我們使用Beautiful Soup。你可以使用Python包管理器 pip 安裝Beautiful Soup:

pip install BeautifulSoup4

安裝好這些庫之後,讓我們開始吧!

檢查網頁

要知道在Python代碼中需要定位哪些元素,首先需要檢查網頁。

要從Tech Track Top 100 companies收集數據,可以通過右鍵單擊感興趣的元素來檢查頁面,然後選擇檢查。這將打開HTML代碼,我們可以在其中看到每個欄位包含在其中的元素。

Tech Track Top 100 companies連結:

http://www.fasttrack.co.uk/league-tables/tech-track-100/league-table/

 


右鍵單擊感興趣的元素並選擇「Inspect」,顯示html元素。

由於數據存儲在一個表中,因此只需幾行代碼就可以直接獲取數據。如果您想練習抓取網站,這是一個很好的例子,也是一個好的開始,但請記住,它並不總是那麼簡單!

所有100個結果都包含在<tr> 元素的行中,並且這些在一頁上都可見。情況並非總是如此,當結果跨越多個頁面時,您可能需要更改網頁上顯示的結果數量,或者遍歷所有頁面以收集所有信息。

League Table網頁上顯示了包含100個結果的表。檢查頁面時,很容易在html中看到一個模式。結果包含在表格中的行中:

<table class="tableSorter">

重複的行<tr> 將通過在Python中使用循環來查找數據並寫入文件來保持我們的代碼最小化!

附註:可以做的另一項檢查是網站上是否發出了HTTP GET請求,該請求可能已經將結果作為結構化響應(如JSON或XML格式)返回。您可以在檢查工具的網絡選項卡中進行檢查,通常在XHR選項卡中進行檢查。刷新頁面後,它將在加載時顯示請求,如果響應包含格式化結構,則使用REST客戶端(如Insomnia)返回輸出通常更容易。

刷新網頁後,頁面檢查工具的網絡選項卡

使用Beautiful Soup解析網頁html

現在您已經查看了html的結構並熟悉了將要抓取的內容,是時候開始使用Python了!

第一步是導入將用於網絡爬蟲的庫。我們已經討論過上面的BeautifulSoup,它有助於我們處理html。我們導入的下一個庫是urllib,它連接到網頁。最後,我們將輸出寫入csv,因此我們還需要導入csv 庫。作為替代方案,可以在此處使用json庫。

# import libraries
from bs4 import BeautifulSoup
import urllib.request
import csv

下一步是定義您正在抓取的網址。如上一節所述,此網頁在一個頁面上顯示所有結果,因此此處給出了地址欄中的完整url:

# specify the url
urlpage =  'http://www.fasttrack.co.uk/league-tables/tech-track-100/league-table/'

然後我們建立與網頁的連接,我們可以使用BeautifulSoup解析html,將對象存儲在變量'soup'中:

# query the website and return the html to the variable 'page'
page = urllib.request.urlopen(urlpage)
# parse the html using beautiful soup and store in variable 'soup'
soup = BeautifulSoup(page, 'html.parser')

我們可以在這個階段列印soup變量,它應該返回我們請求網頁的完整解析的html。

print(soup)

如果存在錯誤或變量為空,則請求可能不成功。可以使用urllib.error模塊在此時實現錯誤處理。

搜索html元素

由於所有結果都包含在表中,我們可以使用find 方法搜索表的soup對象。然後我們可以使用find_all 方法查找表中的每一行。

如果我們列印行數,我們應該得到101的結果,100行加上標題。

# find results within table
table = soup.find('table', attrs={'class': 'tableSorter'})
results = table.find_all('tr')
print('Number of results', len(results))

因此,我們可以對結果進行循環以收集數據。

列印soup對象的前兩行,我們可以看到每行的結構是:

<tr>
<th>Rank</th>
<th>Company</th>
<th>Location</th>
<th>Year end</th>
<th style="text-align:right;">Annual sales rise over 3 years</th>
<th style="text-align:right;">Latest sales £000s</th>
<th style="text-align:right;">Staff</th>
<th>Comment</th>
<!--                            <th>FYE</th>-->
</tr>
<tr>
<td>1</td>
<td><a href="http://www.fasttrack.co.uk/company_profile/wonderbly-3/"><span>Wonderbly</span></a>Personalised children's books</td>
<td>East London</td>
<td>Apr-17</td>
<td style="text-align:right;">294.27%</td>
<td style="text-align:right;">*25,860</td>
<td style="text-align:right;">80</td>
<td>Has sold nearly 3m customisable children’s books in 200 countries</td>
<!--                                            <td>Apr-17</td>-->
</tr>

表格中有8欄:Rank,Company,Location,Year End,Annual Sales Rise,Latest Sales, Staff and Comments,所有這些都是我們可以保存的感興趣的數據。

網頁的所有行的結構都是一致的(對於所有網站來說可能並非總是如此!)。因此,我們可以再次使用find_all 方法將每一列分配給一個變量,那麼我們可以通過搜索<td> 元素來寫入csv或JSON。

循環遍曆元素並保存變量

在Python中,將結果附加到一個列表中是很有用的,然後將數據寫到一個文件中。我們應該在循環之前聲明列表並設置csv的頭文件,如下所示:

# create and write headers to a list 
rows = []
rows.append(['Rank', 'Company Name', 'Webpage', 'Description', 'Location', 'Year end', 'Annual sales rise over 3 years', 'Sales £000s', 'Staff', 'Comments'])
print(rows)

這將列印出我們添加到包含標題的列表的第一行。

你可能會注意到表格中有一些額外的欄位Webpage和Description不是列名,但是如果你仔細看看我們列印上面的soup變量時的html,那麼第二行不僅僅包含公司名稱。我們可以使用一些進一步的提取來獲取這些額外信息。

下一步是循環結果,處理數據並附加到可以寫入csv的rows。

在循環中查找結果:

# loop over results
for result in results:
    # find all columns per result
    data = result.find_all('td')
    # check that columns have data 
    if len(data) == 0: 
        continue

由於表中的第一行僅包含標題,因此我們可以跳過此結果,如上所示。它也不包含任何<td>元素,因此在搜索元素時,不會返回任何內容。然後,我們可以通過要求數據的長度為非零來檢查是否只處理包含數據的結果。

然後我們可以開始處理數據並保存到變量中。

    # write columns to variables
    rank = data[0].getText()
    company = data[1].getText()
    location = data[2].getText()
    yearend = data[3].getText()
    salesrise = data[4].getText()
    sales = data[5].getText()
    staff = data[6].getText()
    comments = data[7].getText()

以上只是從每個列獲取文本並保存到變量。但是,其中一些數據需要進一步清理以刪除不需要的字符或提取更多信息。

數據清理

如果我們列印出變量company,該文本不僅包含公司名稱,還包含描述。我們然後列印sales,它包含不需要的字符,如腳註符號,最好刪除。

    print('Company is', company)
    # Company is WonderblyPersonalised children's books          
    print('Sales', sales)
    # Sales *25,860

我們希望將company 分為公司名稱和描述,我們可以用幾行代碼實現。再看一下html,對於這個列,有一個 <span> 元素只包含公司名稱。此列中還有一個連結指向網站上的另一個頁面,其中包含有關該公司的更多詳細信息。我們將在稍後使用它!

<td><a href="http://www.fasttrack.co.uk/company_profile/wonderbly-3/"><span>Wonderbly</span></a>Personalised children's books</td>

要將company 分成兩個欄位,我們可以使用find方法保存<span>元素,然後使用strip 或replace 從company 變量中刪除公司名稱,這樣它只留下描述。

要從sales中刪除不需要的字符,我們可以再次使用strip和replace 方法!

    # extract description from the name
    companyname = data[1].find('span', attrs={'class':'company-name'}).getText()    
    description = company.replace(companyname, '')
    
    # remove unwanted characters
    sales = sales.strip('*').strip('†').replace(',','')

我們要保存的最後一個變量是公司網站。如上所述,第二列包含指向另一個頁面的連結,該頁面具有每個公司的概述。 每個公司頁面都有自己的表格,大部分時間都包含公司網站。

 

檢查公司頁面上的url元素

要從每個表中抓取url並將其保存為變量,我們需要使用與上面相同的步驟:

查看一些公司頁面,如上面的屏幕截圖所示,網址位於表格的最後一行,因此我們可以在最後一行內搜索<a>元素。

    # go to link and extract company website
    url = data[1].find('a').get('href')
    page = urllib.request.urlopen(url)
    # parse the html 
    soup = BeautifulSoup(page, 'html.parser')
    # find the last result in the table and get the link
    try:
        tableRow = soup.find('table').find_all('tr')[-1]
        webpage = tableRow.find('a').get('href')
    except:
        webpage = None

也有可能出現公司網站未顯示的情況,因此我們可以使用try except條件,以防萬一找不到網址。

一旦我們將所有數據保存到變量中,我們可以在循環中將每個結果添加到列表rows。

    # write each result to rows
    rows.append([rank, company, webpage, description, location, yearend, salesrise, sales, staff, comments])

print(rows)

然後可以試著在循環外列印變量,在將其寫入文件之前檢查它是否符合您的預期!

寫入輸出文件

如果想保存此數據以進行分析,可以用Python從我們列表中非常簡單地實現。

# Create csv and write rows to output file
with open('techtrack100.csv','w', newline='') as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerows(rows)

運行Python腳本時,將生成包含100行結果的輸出文件,您可以更詳細地查看這些結果!

尾語

這是我的第一個教程,如果您有任何問題或意見或者不清楚的地方,請告訴我!

Web Development

https://towardsdatascience.com/tagged/web-development?source=post

Python

https://towardsdatascience.com/tagged/python?source=post

Web Scraping

https://towardsdatascience.com/tagged/web-scraping?source=post

Data Science

https://towardsdatascience.com/tagged/data-science?source=post

Programming

https://towardsdatascience.com/tagged/programming?source=post

 

原文標題:

Data Science Skills: Web scraping using python

原文連結: 

https://towardsdatascience.com/data-science-skills-web-scraping-using-python-d1a85ef607ed

譯者簡介:田曉寧,質量管理專家,國際認證精益六西格瑪黑帶,19年從業經驗;軟體工程專家,擁有CMMI ATM證書,曾主導公司通過CMMI 5級評估;精通ISO9000和ISO27000體系,長期擔任公司質量和信息安全主任審核員,每年審核超過50個項目或部門;擁有PMP證書,擔任公司項目管理內訓師,具有項目管理和系統開發實戰經驗。

「完」

本次轉自:THU數據派 微信公眾號;

版權聲明:本號內容部分來自網際網路,轉載請註明原文連結和作者,如有侵權或出處有誤請和我們聯繫。

相關焦點

  • 用Python進行Web爬取數據
    在本文中,我們將詳細學習如何使用Beautiful Soup構建web ScraperScrapyScrapy是用於大規模Web抓取的Python框架。它為你提供了從網站中高效提取數據,根據需要進行處理並以你喜歡的結構和格式存儲數據所需的所有工具。你可以在這裡閱讀更多有關Scrapy的信息。
  • python : 利用 asyncio 進行快速抓取
    數據抓取是一個經常在python的討論中出現的主題。有很多方法可以用來進行web數據抓取,然而其中好像並沒有一個最好的辦法。有一些如scrapy這樣十分成熟的框架,更多的則是像mechanize這樣的輕量級庫。DIY自己的解決方案同樣十分流行:你可以使用requests、beautifulsoup或者pyquery來實現。
  • 手把手教你用Python抓取AWS的日誌(CloudTrail)數據
    本文手把手,教你使用python進行AWS的CloudTrail配置,進行日誌抓取。進行數據分析,發現數據價值!  如今是雲的時代,許多公司都把自己的IT架構部署在基礎架構雲(IaaS)上。著名的IaaS提供商有亞馬遜,微軟(Azure),IBM等,國內也有諸如阿里雲等。其中,亞馬遜毫無疑問是該市場的領軍者。
  • Tensorflow實戰系列:手把手教你使用LSTM進行文本分類(附完整代碼)
    【導讀】專知小組計劃近期推出Tensorflow實戰系列,計劃教大家手把手實戰各項子任務。
  • 5種流行的Web抓取Python庫,你用過哪種?
    為了緩解這種「數據焦慮」,分析師或數據科學家們練就了必備的技能之一:網站抓取。 用Python執行網站抓取很方便,有大量的庫可以使用,但頭疼的地方也在於此,如何決定哪一個庫適合自己的特定項目?哪個Python庫最靈活?
  • 手把手教你用python搶票回家過年 !(附代碼)
    本文教大家用Python寫出搶火車票代碼以及實戰。首先看看如何快速查看剩餘火車票?當你想查詢一下火車票信息的時候,你還在上12306官網嗎?或是打開你手機裡的APP?下面讓我們來用Python寫一個命令行版的火車票查看器, 只要在命令行敲一行命令就能獲得你想要的火車票信息!如果你剛掌握了Python基礎,這將是個不錯的小練習。接口設計一個應用寫出來最終是要給人使用的,哪怕只是給你自己使用。所以,首先應該想想你希望怎麼使用它?
  • 小課堂:如何用Excel抓取網頁數據
    很明顯,朋友圈的裡的python廣告看多了。想學習數據爬取,何用python?用Excel就可以了。然後你會看到網頁的原始碼,你不需要懂,只要看到當前高亮的代碼中,包含以下任意的標籤,就表示網頁用了table標籤,可以用這個方法。
  • python數據抓取3種方法總結
    這篇文章主要給大家介紹了關於python數據抓取的3種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值
  • python web學習路線知識點分享!
    如果你想做python web相關的東西,下邊這些東西可以參考學習:基礎:linux命令,計算機網絡,python語言,http協議,基礎算法數據>結構python: 內置庫,爬蟲庫,web框架,資料庫接口等。
  • 手把手教小白網申之Applyweb系統 圖文教程
    無分享 不寄託繼dolphin的「手把手教小白網申系列之VT」之後,LZ也把自己網申
  • python語言在全球廣泛應用
    很簡單,還是不能去理解如何利用一些簡單的python語法去實現這些簡單的功能。比如說同樣是logistic回歸,這麼多基礎的框架,如果用python來實現,你還得去看一堆代碼,然後再自己手寫一遍代碼。那麼在日常的實際工作中,到底需要哪些簡單的工具和代碼來解決實際的問題呢?
  • 小學生在網吧用python抓取LOL英雄皮膚,步驟簡單,附帶所有源碼
    你也許或一定玩過LOL英雄聯盟,但你一定沒有嘗試過用Python抓取LOL的各種英雄皮膚。隨著python在中小教育中的普及,就連小學生也開始能用python抓取LOL英雄皮膚了,不得不說,這以後買皮膚剩下的錢,都可以輕輕鬆鬆談場初戀了!
  • 用Python構建數據科學Web應用程式
    在本文中,我將向你展示如何使用streamlit python庫快速構建一個簡單的數據驅動web應用程式,只需幾行代碼。作為一名數據科學家或機器學習工程師,能夠部署我們的數據科學項目是很重要的。傳統的使用Django或Flask這樣的框架來部署機器學習模型可能是一項艱巨和/或耗時的任務。
  • 如何用Python和Scrapy將Web轉化為數據
    基本上,每個web頁面都以HTML格式從伺服器返回。這意味著我們實際的數據被很好地打包在HTML元素中。它使得檢索特定數據的整個過程非常簡單和直接。本教程將是您學習使用Python程式語言進行web抓取的最終指南。首先,我將向您介紹一些基本示例,以使您熟悉web抓取。稍後,我們將使用這些知識從Livescore中提取。
  • 值得收藏的45個Python優質資源(附連結)
    如何使用 Python 中的 Scrapy、SQL 和 Matplotlib 等庫進行網頁抓取,並獲取網頁數據分析你可以通過這篇文章學習到網頁爬取知識,並用於實踐中。高級的網頁抓取教程:繞過「403禁止」,驗證碼等問題http://sangaline.com/post/advanced-web-scraping-tutorial/10.
  • 代碼跑得慢甩鍋Python?手把手教你如何給代碼提速30%
    其實某個特定程序(無論使用何種程式語言)的運行速度是快還是慢,在很大程度上取決於編寫該程序的開發人員自身素質,以及他們編寫優化而高效代碼的能力。Medium上一位小哥就詳細講了講如何讓python提速30%,以此證明代碼跑得慢不是python的問題,而是代碼本身的問題。
  • Python爬蟲:一些常用的爬蟲技巧總結
    來源:開源中國 http://my.oschina.net/jhao104/blog/647308 作者: j_hao104用python也差不多一年多了,python應用最多的場景還是web快速開發、爬蟲、自動化運維:寫過簡單網站、寫過自動發帖腳本、寫過收發郵件腳本、寫過簡單驗證碼識別腳本。
  • 工具&方法 | 6行代碼教你用python做OLS回歸(內附CFPS實例)
    如果你還不會,那麼本文也會介紹一些 python 語法的基礎內容,方便大家理解。隨著數據資源的日漸豐富,學者們越來越多的需要接觸到大數據的處理,許多學者還是習慣使用 Stata 對數據進行處理,而 Stata 由於其自身的限制,在處理大數據集時要麼需要強勁的處理性能(昂貴的硬體成本),要麼需要等待較長時間(更加昂貴的時間成本)。
  • Python爬蟲:抓取One網頁上的每日一話和圖
    現在也沒有深入,用哪學哪吧。curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"pip install virtualenvpip install requests beautifulsoup4參考這裡 (http://wuchong.me/blog/2014/04/24/easy-web-scraping-with-python
  • 獨家 | 手把手教你如何用Python從PDF文件中導出數據(附連結)
    如果你真的好奇的話,儘管可以深入地研究它們的原始碼。無論如何,我認為我們可以大致照以上代碼行事。我們做的第一件事就是創建一個資源管理器的實例。然後通過Python的輸入輸出(io)模塊創建一個似文件對象。如果你使用的是Python 2,你應該使用StringIO模塊。接下來的步驟是創建一個轉換器。