Đưa các bảng HTML vào khung dữ liệu bằng BeautifulSoup

Bài viết đăng tại: https://programming.laptrinh.site

Python có nhiều gói khác nhau để làm việc với việc xem xét các yêu cầu của dự án; một là BeautifulSoup , được sử dụng để phân tích các tài liệu HTML và XML.

Nó tạo ra một cây phân tích cú pháp cho các trang được phân tích cú pháp mà chúng ta có thể sử dụng để trích xuất thông tin (dữ liệu) từ HTML, điều này có lợi cho việc quét web. Hướng dẫn hôm nay dạy cách cạo các bảng HTML thành một khung dữ liệu bằng cách sử dụng gói BeautifulSoup .

Sử dụng BeautifulSoup để quét các bảng HTML vào khung dữ liệu

Không nhất thiết là chúng tôi luôn nhận được dữ liệu được sắp xếp và làm sạch mọi lúc.

Đôi khi, chúng tôi cần dữ liệu có sẵn trên các trang web. Đối với điều đó, chúng ta phải có khả năng thu thập nó.

May mắn thay, gói BeautifulSoup của Python có giải pháp cho chúng tôi. Hãy tìm hiểu cách chúng ta có thể sử dụng gói này để sắp xếp các bảng vào một khung dữ liệu.

Trước tiên, chúng ta cần cài đặt gói này trên máy của mình để có thể nhập gói đó vào tập lệnh Python. Chúng ta có thể sử dụng lệnh pip để cài đặt BeautifulSoup trên hệ điều hành Windows.

pip install beautifulsoup

Bạn có thể truy cập tài liệu này để biết thêm thông tin. Chúng tôi biết rằng chúng tôi không quen thuộc với cấu trúc cơ bản của bảng HTML, điều quan trọng cần biết khi tìm hiểu; hãy hiểu điều đó để làm theo hướng dẫn này.

cấu trúc bảng html

Trong bảng trên, TH có nghĩa là tiêu đề bảng, TR có nghĩa là hàng của bảng và TD có nghĩa là dữ liệu bảng (chúng tôi gọi nó là các ô). Như chúng ta có thể thấy rằng mỗi hàng của bảng có nhiều dữ liệu bảng, vì vậy chúng ta có thể dễ dàng lặp lại từng hàng để trích xuất thông tin.

Bây giờ, hãy tìm hiểu nó từng bước một.

  • Nhập thư viện
    import requests import pandas as pd from bs4 import BeautifulSoup

    Trước tiên, chúng ta cần nhập tất cả các thư viện này, thư viện pandas để làm việc với khung dữ liệu, bs4 (súp đẹp) để quét dữ liệu và thư viện requests để thực hiện các yêu cầu HTTP bằng Python.

  • Tải xuống nội dung từ trang web
     web_url = "https://pt.wikipedia.org/wiki/Lista_de_bairros_de_Manaus" data = requests . get(web_url) . text # data # print(data) # print(type(data))

    Tại đây, chúng tôi lưu URL được yêu cầu trong biến web_url và thực hiện yêu cầu HTTP bằng cách sử dụng mô-đun requests .

    Chúng tôi sử dụng .get() từ mô-đun requests để truy xuất dữ liệu từ web_url chỉ định trong khi .text có nghĩa là chúng tôi muốn truy xuất dữ liệu dưới dạng chuỗi.

    Vì vậy, nếu chúng tôi in dưới dạng print(type(data)) , chúng tôi sẽ thấy rằng chúng tôi đã truy xuất HTML của toàn bộ trang dưới dạng một chuỗi. Bạn có thể thử bằng cách in data , print(data)print(type(data)) .

    Tất cả những thứ này đều có trong hàng rào mã ở trên; bạn có thể bỏ ghi chú chúng và thực hành.

  • Tạo đối tượng BeautifulSoup
     beautiful_soup = BeautifulSoup(data, 'html.parser' ) # print(type(beautiful_soup.b))

    Đối tượng BeautifulSoup ( beautiful_soup ) đại diện cho toàn bộ tài liệu được phân tích cú pháp. Vì vậy, có thể nói đó là một tài liệu hoàn chỉnh mà chúng tôi đang cố gắng thu thập.

    Hầu hết, chúng tôi coi nó là đối tượng Tag , cũng có thể được kiểm tra bằng cách sử dụng câu print(type(beautiful_soup.b)) . Bây giờ, chúng ta có HTML hoàn chỉnh của trang được yêu cầu.

    Bước tiếp theo là tìm ra bảng mà chúng ta muốn, chúng ta có thể lấy thông tin từ bảng đầu tiên, nhưng có khả năng có nhiều bảng trên cùng một trang web.

    Vì vậy, việc tìm kiếm bảng cần thiết mà chúng tôi muốn cạo là rất quan trọng. Làm sao? Chúng ta có thể dễ dàng làm điều đó bằng cách kiểm tra mã nguồn.

    Đối với điều đó, right-click bất kỳ đâu trên trang web được yêu cầu và chọn inspect , nhấn Ctrl + Shift + C để chọn các thành phần (được đánh dấu màu đỏ trong ảnh chụp màn hình sau), bạn cũng có thể sử dụng hộp tìm kiếm để tìm các thẻ cụ thể (được đánh dấu màu xanh lục trong ảnh chụp màn hình sau).

    kiểm tra nguyên tố

    Chúng tôi có ba bảng; như thể hiện trong ảnh chụp màn hình ở trên (xem số này trong hộp tìm kiếm, được đánh dấu bằng màu xanh lục), chúng tôi đang sử dụng bảng được đánh dấu với class="wikitable sortable jquery-tablesorter" .

    Vấn đề là, tại sao chúng ta sử dụng thuộc tính class để chọn bảng? Đó là bởi vì các bảng không có bất kỳ tiêu đề nào ngoài thuộc tính class .

  • Xác minh các bảng với các lớp của chúng
    print ( 'Classes of Every table:' ) for table in beautiful_soup . find_all( 'table' ): print (table . get( 'class' ))

    Đầu ra:

     Classes of Every table: ['box-Desatualizado', 'plainlinks', 'metadata', 'ambox', 'ambox-content'] ['wikitable', 'sortable'] ['nowraplinks', 'collapsible', 'collapsed', 'navbox-inner']

    Ở đây, chúng tôi lặp lại tất cả các phần tử <table> để tìm các lớp của chúng thông qua việc lấy thuộc tính class .

  • Tìm kiếm các wikitable sortable và có thể wiki hóa
     tables = beautiful_soup . find_all( 'table' ) table = beautiful_soup . find( 'table' , class_ = 'wikitable sortable' )

    Đầu tiên, chúng ta tạo một danh sách tất cả các bảng và sau đó tìm kiếm bảng có các lớp có thể wikitable và có sortable được.

  • Tạo một khung dữ liệu và điền vào nó
    df = pd.DataFrame(columns=['Neighborhood', 'Zone', 'Area',
    						 'Population', 'Density', 'Homes_count'])
    
    mylist = []
    for table_row in table.tbody.find_all('tr'):
      table_columns = table_row.find_all('td')
    
      if(table_columns != []):
    	  neighbor = table_columns[0].text.strip()
    	  zone = table_columns[1].text.strip()
    	  area = table_columns[2].span.contents[0].strip('&0.')
    	  population = table_columns[3].span.contents[0].strip('&0.')
    	  density = table_columns[4].span.contents[0].strip('&0.')
    	  home_count = table_columns[5].span.contents[0].strip('&0.')
    
    	  mylist.append([neighbor, zone, area, population, density, home_count])
    
    df = pd.DataFrame(mylist,
       columns=['Neighborhood', 'Zone', 'Area', 'Population', 'Density', 'Homes_count'])
    

    Ở đây, chúng tôi xác định một khung dữ liệu với các cột Neighborhood , Zone , Area , Homes_count , DensityPopulation . Sau đó, chúng tôi lặp lại bảng HTML để truy xuất dữ liệu và điền vào khung dữ liệu mà chúng tôi vừa xác định.

  • Sử dụng df.head() để in 5 tài liệu đầu tiên
    print (df . head())

    Đầu ra:

     Neighborhood Zone Area Population Density Homes_count 0 Adrianópolis Centro-Sul 248.45 10459 3560.88 3224 1 Aleixo Centro-Sul 618.34 24417 3340.4 6101 2 Alvorada Centro-Oeste 553.18 76392 11681.73 18193 3 Armando Mendes Leste 307.65 33441 9194.86 7402 4 Betânia Sul 52.51 1294 20845.55 3119

Mã nguồn hoàn chỉnh:

import requests
import pandas as pd
from bs4 import BeautifulSoup

web_url = "https://pt.wikipedia.org/wiki/Lista_de_bairros_de_Manaus"
data = requests.get(web_url).text

beautiful_soup = BeautifulSoup(data, 'html.parser')

print('Classes of Every table:')
for table in beautiful_soup.find_all('table'):
    print(table.get('class'))


tables = beautiful_soup.find_all('table')
table = beautiful_soup.find('table', class_='wikitable sortable')

df = pd.DataFrame(columns=['Neighborhood', 'Zone', 'Area',
                           'Population', 'Density', 'Homes_count'])

mylist = []
for table_row in table.tbody.find_all('tr'):
    table_columns = table_row.find_all('td')

    if(table_columns != []):
        neighbor = table_columns[0].text.strip()
        zone = table_columns[1].text.strip()
        area = table_columns[2].span.contents[0].strip('&0.')
        population = table_columns[3].span.contents[0].strip('&0.')
        density = table_columns[4].span.contents[0].strip('&0.')
        home_count = table_columns[5].span.contents[0].strip('&0.')

        mylist.append([neighbor, zone, area, population, density, home_count])

df = pd.DataFrame(mylist,
     columns=['Neighborhood', 'Zone', 'Area', 'Population', 'Density', 'Homes_count'])

print(df.head())

Đầu ra:

 Classes of Every table: ['box-Desatualizado', 'plainlinks', 'metadata', 'ambox', 'ambox-content'] ['wikitable', 'sortable'] ['nowraplinks', 'collapsible', 'collapsed', 'navbox-inner'] Neighborhood Zone Area Population Density Homes_count 0 Adrianópolis Centro-Sul 248.45 10459 3560.88 3224 1 Aleixo Centro-Sul 618.34 24417 3340.4 6101 2 Alvorada Centro-Oeste 553.18 76392 11681.73 18193 3 Armando Mendes Leste 307.65 33441 9194.86 7402 4 Betânia Sul 52.51 1294 20845.55 3119

URL Link

https://laptrinh.site/dua-cac-bang-html-vao-khung-du-lieu-bang-beautifulsoup/

Viết bởi Duy Mạnh. Đã đăng ký bản quyền tác giả tại Creativecommons và DMCA