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

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


翻譯:田曉寧

校對:丁楠雅

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

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


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


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

在本教程中,我將介紹一個簡單的例子,說明如何抓取一個網站,我將從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/


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


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


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

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

所有100個結果都包含在

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

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


重複的行

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

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


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


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


使用Beautiful Soup解析網頁html

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

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

# import librariesfrom bs4 import BeautifulSoupimport urllib.requestimport csv


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

# specify the urlurlpage = '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 tabletable = soup.find('table', attrs={'class': 'tableSorter'})results = table.find_all('tr')print('Number of results', len(results))


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

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


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

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


要將company 分成兩個字段,我們可以使用find方法保存元素,然後使用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(',','')


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


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


檢查公司頁面上的url元素


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

  • 在fast track網站上找到具有公司頁面網址的元素
  • 向每個公司頁面網址發出請求
  • 使用Beautifulsoup解析html
  • 找到感興趣的元素


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

# 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 filewith 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

譯者簡介

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


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

— 完 —

關注清華-青島數據科學研究院官方微信公眾平臺“THU數據派”及姊妹號“數據派THU”獲取更多講座福利及優質內容。

Rank CompanyLocationYear endAnnual sales rise over 3 yearsLatest sales £000sStaffComment
1 Personalised children's booksEast LondonApr-17294.27%*25,86080Has sold nearly 3m customisable children’s books in 200 countries
元素來寫入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 resultsfor result in results: # find all columns per result data = result.find_all('td') # check that columns have data if len(data) == 0: continue


由於表中的第一行僅包含標題,因此我們可以跳過此結果,如上所示。它也不包含任何

元素,因此在搜索元素時,不會返回任何內容。然後,我們可以通過要求數據的長度為非零來檢查是否只處理包含數據的結果。

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

# 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,對於這個列,有一個 元素只包含公司名稱。此列中還有一個鏈接指向網站上的另一個頁面,其中包含有關該公司的更多詳細信息。我們將在稍後使用它!

Personalised children's books


分享到:


相關文章: