1. 程式人生 > >【Python網路爬蟲】Python維基百科網頁抓取(BeautifulSoup+Urllib2)

【Python網路爬蟲】Python維基百科網頁抓取(BeautifulSoup+Urllib2)

引言:

從網路提取資料的需求和重要性正在變得越來越迫切。 每隔幾個星期,我都會發現自己需要從網路中提取資料。 例如,上週我們正在考慮建立一個關於網際網路上可用的各種資料科學課程的熱度和情緒指數。 這不僅需要找到新的課程,而且還要抓住網路的評論,然後在幾個指標上進行總結!

一、從網上提取資訊的方式

有幾種方法可以從網路中提取資訊。 使用API可能是從網站提取資料的最佳方式。 幾乎所有像Twitter,Facebook,Google,Twitter,StackOverflow這樣的大型網站都提供了API,可以以更加結構化的方式訪問他們的資料。

可悲的是,不是所有的網站都提供了一個API。 有的是因為他們不希望讀者以結構化的方式提取大量的資訊,有的則由於缺乏技術知識而不提供API。 在這些情況下做什麼?此時需要從網站來獲取資訊。

可能還有其他一些方法,如RSS提要,但它們的使用是有限的,因此我沒有把它們包括在這裡的討論中。

二、什麼是網路爬取?

網路爬取是一種從網站提取資訊的計算機軟體技術。 這種技術主要集中在將網路上的非結構化資料(HTML格式)轉換為結構化資料(資料庫或電子表格)。

您可以通過各種方式執行網路抓取,包括使用Google文件幾乎所有的程式語言。 我更傾向於Python,因為它的易用性和豐富的eocsystem。 它有一個名為“BeautifulSoup”的庫來協助這項工作。 在本文中,我將向您展示使用python程式設計學習網頁抓取的最簡單方法。

對於那些需要用非程式設計方式從網頁中提取資訊的人,你也可以看看import.io。 它提供了一個GUI驅動的介面來執行所有基本的網頁抓取操作。

三、網路抓取所需的庫

我們知道,python是一種開源的程式語言。 你可能會發現許多庫來執行一個功能。 因此,有必要找到最好的使用庫。 我更喜歡BeautifulSoup(python庫),因為它很容易和直觀。 準確地說,我將使用兩個Python模組來抓取資料:

  • Urllib2:這是一個可用於獲取URL的Python模組。 它定義了函式和類來幫助URL操作(基本和摘要式身份驗證,重定向,cookie等)。
  • BeautifulSoup:這是一個從網頁中提取資訊的工具。 您可以使用它來提取表格,列表和段落,也可以使用過濾器從網頁中提取資訊。 在本文中,我們將使用最新版本的BeautifulSoup 4。

BeautifulSoup不會為我們提取網頁。 這就是為什麼,我使用urllib2與BeautifulSoup庫結合使用。

除了BeautifulSoup之外,Python還有其他幾個用於HTML抓取的:

  • mechanize
  • scrapemark
  • scrapy

四、基礎知識 - 熟悉HTML(標籤)

在執行網頁抓取時,我們處理html標籤。 因此,我們必須對它們有很好的瞭解。 如果您已經瞭解HTML的基本知識,則可以跳過本節。 以下是HTML的基本語法:

這裡寫圖片描述

這個語法有如下詳述的各種標籤:

1。<!DOCTYPE html>:HTML文件必須以型別宣告開始
2。HTML文件包含在<html></html>之間
3。HTML文件的可見部分在<body></body>之間
4。HTML標題用<h1><h6>標籤定義
5。HTML段落是用<p>標籤定義的

其他有用的HTML標籤:

1。HTML連結用<a>標籤定義,<ahref="http://www.test.com">這是test.com的連結</a>
2。HTML表格定義為<Table>,行定義為<tr>,複數行被劃分為<td>中的資料

這裡寫圖片描述

3。HTML列表以<ul>(無序)和<ol>(有序)開頭。 列表中的每一項都以<li>開頭

五、使用BeautifulSoup來抓取網頁

從維基百科頁面上抓取資料。 我們的最終目標是提取印度國家,工會領土首都的名單。 一些基本的細節,如建立,前資本和其他形式這個維基百科頁面。 讓我們來學習一下這個專案的步驟:

1、Import necessary libraries:

#import the library used to query a website
import urllib2
#specify the url
wiki = "https://en.wikipedia.org/wiki/List_of_state_and_union_territory_capitals_in_India"
#Query the website and return the html to the variable 'page'
page = urllib2.urlopen(wiki)
#import the Beautiful soup functions to parse the data returned from the website
from bs4 import BeautifulSoup
#Parse the html in the 'page' variable, and store it in Beautiful Soup format
soup = BeautifulSoup(page)

2、Use function “prettify” to look at nested structure of HTML page

這裡寫圖片描述

3、Work with HTML tags

Asoup.<tag>: Return content between opening and closing tag including tag.

In[30]:soup.title

Out[30]:<title>List of state and union territory capitals in India - Wikipedia, the free encyclopedia</title>

Bsoup.<tag>.string: Return string within given tag

In [38]:soup.title.string

Out[38]:u'List of state and union territory capitals in India - Wikipedia, the free encyclopedia'

CFind all the links within page’s <a> tags::我們知道,我們可以使用標籤<a>來標記連結。 所以,我們應該選擇soup.a,它應該返回網頁中可用的連結。

In [40]:soup.a 

Out[40]:<a id="top"></a>

以上,你可以看到,我們只有一個輸出。 現在提取<a>中的所有連結,我們將使用“find_all()”

這裡寫圖片描述

以上顯示了所有連結,包括標題,連結和其他資訊。 現在只顯示連結,我們需要迭代每個標籤,然後用get得到“href”返回連結。

這裡寫圖片描述

4、Find the right table

由於我們正在尋找一張表來提取有關州首府的資訊,所以我們應該首先確定正確的表格。 讓我們編寫命令來提取所有table標籤中的資訊。

all_tables=soup.find_all('table')

現在要確定正確的表格,我們將使用表格的屬性“class”並使用它來過濾右邊的表格。 在chrome中,可以通過右鍵點選所需的網頁表格 - >檢查元素 - >複製類名或者通過上述命令的輸出查詢右表的類名。

right_table=soup.find('table', class_='wikitable sortable plainrowheaders')

right_table

這裡寫圖片描述

5.Extract the information to DataFrame

在這裡,我們需要迭代每一行(tr),然後將tr(td)的每個元素分配給一個變數並將其附加到列表中。 我們先來看看錶格的HTML結構

這裡寫圖片描述

在上面,你可以注意到<tr>的第二個元素在標籤<th>而不是<td>中,所以我們需要注意這一點。 現在要訪問每個元素的值,我們將使用每個元素的“find(text = True)”選項。 讓我們看看程式碼:

#Generate lists
A=[]
B=[]
C=[]
D=[]
E=[]
F=[]
G=[]
for row in right_table.findAll("tr"):
    cells = row.findAll('td')
    states=row.findAll('th') #To store second column data
    if len(cells)==6: #Only extract table body not heading
        A.append(cells[0].find(text=True))
        B.append(states[0].find(text=True))
        C.append(cells[1].find(text=True))
        D.append(cells[2].find(text=True))
        E.append(cells[3].find(text=True))
        F.append(cells[4].find(text=True))
        G.append(cells[5].find(text=True))
#import pandas to convert list to data frame

import pandas as pd

df=pd.DataFrame(A,columns=['Number'])

df['State/UT']=B

df['Admin_Capital']=C

df['Legislative_Capital']=D

df['Judiciary_Capital']=E

df['Year_Capital']=F

df['Former_Capital']=G

df

最後,得到資料:

這裡寫圖片描述

六、但是,為什麼我不能使用正則表示式呢?

現在,如果你知道正則表示式,你可能會認為你可以使用正則表示式來編寫程式碼,它可以為你做同樣的事情。 在我用BeautifulSoup和正則表示式做同樣的事情的經驗,我發現:

  • 用BeautifulSoup編寫的程式碼通常比使用正則表示式編寫的程式碼更穩健。 用正則表示式編寫的程式碼需要隨著頁面的變化而改變。 即使BeautifulSoup需要在某些情況下,BeautifulSoup只是相對更好。
  • 正則表示式比BeautifulSoup快得多,在給出相同的結果時,通常是100倍速度。

所以,它歸結為程式碼的速度和魯棒性,在這裡沒有普遍的贏家。 如果你正在尋找的資訊可以用簡單的正則表示式語句來提取。 對於幾乎任何複雜的工作,相較於正則表示式,我更推薦BeautifulSoup。

總結:

本文,我們使用Python“BeautifulSoup”和“urllib2”來研究web抓取方法。 我們也研究了HTML的基礎知識,同時一步一步地執行網頁抓取。 快用它來從網頁收集資料吧!