[Python爬蟲教學]Python網頁爬蟲動態翻頁的實作技巧

[Python爬蟲教學]Python網頁爬蟲動態翻頁的實作技巧
Photo by True Agency on Unsplash
在眾多的網頁中,當要載入的資料量非常龐大時,為了不影響執行效能的情況下,除了會使用滾動捲軸來動態載入更多的資料外,另一種最常見的方式就是利用分頁,來分別顯示特定筆數的資料。

如果Python網頁爬蟲遇到需滾動捲軸,才可爬取更多資料的實作方式,可以參考[Python爬蟲教學]整合Python SeleniumBeautifulSoup實現動態網頁爬蟲文章,而Python網頁爬蟲遇到分頁的網站時,該如何翻頁爬取內容,就是本文要來分享的主題。其中的重點包含:
  • HTTP GET vs POST方法
  • 頁碼使用GET的方式
  • 頁碼使用POST的方式

一、HTTP GET vs  POST方法

在說明Python網頁爬蟲讀取分頁的資料前,先來簡單瞭解一下什麼是HTTPGETPOST方法。

HTTPGET方法就像明信片,在上面需要撰寫目的地的地址及內容,其中的地址就像是請求的網址,而內容就像是接在網址後面的參數(querystring),只要拿到這個明信片(網址)的人,都知道要寄送到哪裡及內容是什麼。

HTTPPOST方法就像一般的信件,在信封上需撰寫目的地的地址,而信件內容會在信封中,所以拿到這封信的人只知道會寄送到哪裡,但不會知道內容是什麼,就像是知道請求的網址,但是其中送到伺服器端的資料,無法在網址知道。

瞭解了這兩個HTTP方法的基本觀念後,接下來就使用兩個網站,來分別說明頁碼使用GETPOST方式處理的網站,Python網頁爬蟲該如何翻頁爬取資料。

二、頁碼使用GET的方式

大部分的網站分頁,都是使用GET方法來處理,這邊以Inside 硬塞的網路趨勢觀察網站的「AI類別為例,可以看到網址如下:
當切換至第二頁時,網址為:
這就是典型GET方法的分頁方式,從網址就可以知道目的地網址及傳至伺服器端的頁碼參數(page),當變換page參數的值時,就可以前往對應的頁碼網頁。

接下來,在網頁上按F12鍵,進入開發者模式後,先來看一下要爬取的文章標題HTML原始碼架構,如下圖:
瞭解它的階層架構,就可以利用BeautifulSoup套件爬取第一頁的內容,如下範例
from bs4 import BeautifulSoup
import requests


# 連結網站
response = requests.get(
	"https://www.inside.com.tw/tag/AI?page=1")

# HTML原始碼解析
soup = BeautifulSoup(response.text, "html.parser")

# 取得所有class為post_title的

titles = soup.find_all("h3", {"class": "post_title"}) for title in titles: print(title.select_one("a").getText()) # 取得標題文字

執行結果
成功爬取第一頁的內容,就可以使用Python迴圈,透過變換網址頁碼參數(page)的方式,翻頁爬取網頁內容了,如下範例
from bs4 import BeautifulSoup
import requests

for page in range(1, 4):  # 執行1~3頁

    # 連結網站
    response = requests.get(
        "https://www.inside.com.tw/tag/AI?page=" + str(page))

    # HTML原始碼解析
    soup = BeautifulSoup(response.text, "html.parser")

    # 取得所有class為post_title的

titles = soup.find_all("h3", {"class": "post_title"}) print(f"====================第{str(page)}頁====================") for title in titles: print(title.select_one("a").getText()) # 取得連結的標題文字

範例中只爬取1~3頁的內容,如果要更多頁的話可以自行調整第4行的range()參數。另外,要特別注意的是,Python迴圈讀取range()函式時,page的型別為數值(Integer),所以為了要加在網址後面,需透過str()函式轉型成字串,如範例中第8行。詳細的Python轉型教學可以參考[Python教學]Python數值與型別轉換的重要觀念文章。

三、頁碼使用POST的方式

另一個網站頁碼切換的方式會採用POST方法,就像信件一樣,知道寄送的地址(網址),卻不會知道信封中的內容(送往伺服器的頁碼參數)。

這邊以591房屋交易網的「租屋類別為例,可以看到網址如下:
由於是使用POST方法來撈取網頁資料,所以當切換到第二頁時,會發現網址並不會像Inside 硬塞的網路趨勢觀察網站一樣,會出現頁碼的參數,而是和第一頁的網址一模一樣,都沒有動靜。

這時候,就需要結合Selenium套件,透過模擬使用者點擊下一頁按鈕,來進行換頁的動作。同樣先看一下所要爬取的租屋標題HTML原始碼結構,如下圖:
接著,就可以利用Selenium套件開啟瀏覽器並且連線至591房屋交易網的「租屋類別,再使用BeautifulSoup套件爬取第一頁的租屋標題如下範例
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup


options = Options()
options.add_argument("--disable-notifications")  # 取消所有的alert彈出視窗

browser = webdriver.Chrome(
    ChromeDriverManager().install(), chrome_options=options)

browser.get("https://rent.591.com.tw/")

area = browser.find_element_by_id("area-box-close")
area.click()  # 取消「選擇縣市」的div視窗

soup = BeautifulSoup(browser.page_source, "html.parser")

# 取得所有class為pull-left infoContent的
  • 標籤 elements = soup.find_all("li", {"class": "pull-left infoContent"}) for element in elements: # 取得
  • 標籤下的

    標籤,再取得

    標籤下的標籤文字,並且去掉空白 title = element.find("h3").find("a").getText().strip() print(title)

  • 執行結果
    由於要點擊下一頁按鈕來進行換頁,所以,來觀察一下頁碼區域的HTML原始碼,如下圖:
    得知下一頁按鈕的樣式類別(class)為「pageNext」後,就可以利用Selenium套件進行元素的定位與點擊換頁了,如下範例
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from webdriver_manager.chrome import ChromeDriverManager
    from bs4 import BeautifulSoup
    
    
    options = Options()
    options.add_argument("--disable-notifications")  # 取消所有的alert彈出視窗
    
    browser = webdriver.Chrome(
        ChromeDriverManager().install(), chrome_options=options)
    
    browser.get("https://rent.591.com.tw/")
    
    area = browser.find_element_by_id("area-box-close")
    area.click()  # 取消「選擇縣市」的div視窗
    
    soup = BeautifulSoup(browser.page_source, "html.parser")
    
    # 取得所有class為pull-left infoContent的
  • 標籤 elements = soup.find_all("li", {"class": "pull-left infoContent"}) for element in elements: # 取得
  • 標籤下的

    標籤,再取得

    標籤下的標籤文字,並且去掉空白 title = element.find("h3").find("a").getText().strip() print(title) page_next = browser.find_element_by_class_name("pageNext") page_next.click() # 點擊下一頁按鈕

  • 最後,透過Python迴圈重覆執行以上的動作,來達到動態翻頁爬取網頁內容的目的,如下範例
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from webdriver_manager.chrome import ChromeDriverManager
    from bs4 import BeautifulSoup
    import time
    
    
    options = Options()
    options.add_argument("--disable-notifications")  # 取消所有的alert彈出視窗
    
    browser = webdriver.Chrome(
        ChromeDriverManager().install(), chrome_options=options)
    
    browser.get("https://rent.591.com.tw/")
    
    area = browser.find_element_by_id("area-box-close")
    area.click()  # 取消「選擇縣市」的div視窗
    
    for page in range(1, 3):  # 執行1~2頁
    
        soup = BeautifulSoup(browser.page_source, "html.parser")
    
        # 取得所有class為pull-left infoContent的
  • 標籤 elements = soup.find_all("li", {"class": "pull-left infoContent"}) print(f"==========第{str(page)}頁==========") for element in elements: # 取得
  • 標籤下的

    標籤,再取得

    標籤下的標籤文字,並且去掉空白 title = element.find("h3").find("a").getText().strip() print(title) page_next = browser.find_element_by_class_name("pageNext") page_next.click() # 點擊下一頁按鈕 time.sleep(10) # 暫停10秒

  • 四、小結

    以上就是Python網頁爬蟲在遇到有分頁的網站時,能夠動態換頁爬取網頁內容的實作方式,詳細的程式碼可以參考下方的GitHub網址,希望有幫助到大家。

    如果您喜歡我的文章,請幫我按五下Like(使用GoogleFacebook帳號免費註冊),支持我創作教學文章,回饋由LikeCoin基金會出資,完全不會花到錢,感謝大家。

    有想要看的教學內容嗎?歡迎利用以下的Google表單讓我知道,將有機會成為教學文章,分享給大家😊

    Python網頁爬蟲推薦課程

    你可能有興趣的文章
    Learn Code With Mike

    Mike是一位網頁開發工程師和專欄作家,同時也是「Learn Code With Mike」的創辦人,致力於撰寫Python「入門教學、爬蟲應用、資料分析與網頁開發」等主題的教學文章,未來也會開設線上課程,利用簡潔易懂和範例逐步教學的方式,幫助讀者學習Python程式語言,開發屬於自己的應用程式。

    評論
    你可能也喜歡
    熱門文章