Введение

В этой статье будут рассмотрены основные методы удаления данных из Интернета с использованием различных методов, таких как использование поисковых роботов и библиотек, таких как BeautifulSoup, urllib и запросы для эффективного сбора и анализа данных.

Все коды находятся в репозитории GitHub, нажмите здесь, чтобы увидеть коды.

Веб-парсинг с помощью BeautifulSoup

Beautiful Soup - это библиотека Python для извлечения данных из файлов HTML и XML. Он работает с вашим любимым парсером, обеспечивая идиоматические способы навигации, поиска и изменения дерева синтаксического анализа.

В этом упражнении мы извлечем таблицу на основе истории версий Android (первая таблица) со страницы: https://en.wikipedia.org/wiki/Android_version_history

Получение данных HTML-страницы с помощью urllib

from urllib.request import urlopen
android_url = "https://en.wikipedia.org/wiki/Android_version_history"
android_data = urlopen(android_url) 
# android_data is an http response object
android_html = android_data.read()
# we can get the whole html of that page by using the read() method on the android_data (object)
android_html = android_data.read()
android_data.close()

Мы используем urlopen (url) для отправки HTTP-запроса на указанный URL-адрес, и мы получаем ответ, и мы используем этот объект ответа для извлечения HTML-страницы с помощью метода read () Встроенный метод. Не забудьте закрыть соединение в конце.

Теперь мы воспользуемся библиотекой BeautifulSoup для анализа полученного нами HTML-кода.

from bs4 import BeautifulSoup as soup
android_soup = soup(android_html, 'html.parser')
tables = android_soup.findAll('table', {'class':'wikitable'})
print("Number of Tables: {}".format(len(tables)))

Вывод:

Number of Tables: 31

Сначала мы должны создать объект класса супа с помощью и указать парсер как «html.parser». Затем мы воспользуемся методом findall () для обнаружения определенного элемента и предоставим любой дополнительный атрибут поиска в качестве второго параметра в форме словаря, в нашем случае нам нужны таблицы, которые принадлежат к классу «wikitable». .

Мы можем использовать встроенный в браузер элемент проверки, чтобы найти тег элемента и любой элемент для поиска, например имя класса или конкретный идентификатор, и передать его в качестве словаря.

Пример findall ():

Постараемся найти все элементы с тегом «h1»:

a = android_soup.findAll('h1', {})
# it return a list of matching objects
print(a)
print(type(a))
print(len(a))

Вывод:

[<h1 class="firstHeading" id="firstHeading" lang="en">Android version history</h1>]
<class 'bs4.element.ResultSet'>
1

Мы получаем только 1 результат поиска тегов ℎ1h1, поскольку эта веб-страница содержит только один тег h1, который является заголовком страницы, как показано ниже:

Перед тем как продолжить, посмотрим на таблицу, которую мы пытаемся очистить.

Как мы видим, первые две строки использовать нельзя, потому что этим версиям Android не присвоено кодовое имя.

Точно так же последняя строка бесполезна, поскольку она содержит отсутствующие значения, и мы также можем удалить последний столбец, столбец Ссылки, поскольку он не содержит никакой информации.

Выберем данные первой таблицы и извлечем из нее заголовки столбцов:

android_table = tables[0]
headers = android_table.findAll('th')
# We will use these headers as columns names hence we have to store them in a variable
column_titles = [ct.text for ct in headers]
# slice out the carriage return (\n)
column_titles = [ct.text[:-1] for ct in headers]
# We wont be using the last column('References') hence we will remove it from our column names:
column_titles = column_titles[:-1]
print(len(column_titles))
print(column_titles)

Вывод:

4
['Name', 'Version number(s)', 'Initial release date', 'API level']

Теперь мы получим строки таблицы и завершим сортировку и очистку данных, сохранив все в переменной table_rows:

rows_data = android_table.findAll('tr')[1:]
print("Total number of rows: {}".format(len(rows_data)))
# We will start with the third row as the first two rows have no name for the software versions
rows_data = rows_data[2:]
print("Number of rows we are going to display: {}".format(len(rows_data)))

Вывод:

Total number of rows: 18
Number of rows we are going to display: 16

Финальный фрагмент кода, чтобы собрать все воедино:

table_rows = []
for row_id, row in enumerate(rows_data):
    
    # We will skip the last row as it contains missing value
    if row_id == 15:
        continue
    
    current_row = []
    row_data = row.findAll('td', {})
    
    for col_id, data in enumerate(row_data):
        
        # We will skip the last column(References) as it does not contain any major information
        if col_id == 4:
            continue
            
        # We will also replace any commas(',') present in the data as we have to store the data in a csv
        # file
        text = data.text
        text = text.replace(",", "")[:-1] # We are slicing the data as all the elemnets contain a carriage
        # return('\n') at the end
        current_row.append(text)
            
    table_rows.append(current_row)

Переменная table_rows представляет собой вложенный список, который содержит данные всех строк, мы можем сохранить эти данные в файле CSV, а затем отобразить его как фрейм данных (используя pandas):

import pandas as pd
pd.DataFrame(table_rows, columns=column_titles).to_csv("Data/android_version_history_pandas.csv", index=False)
# Reading CSV file and Displaying data
data_1 = pd.read_csv("Data/android_version_history.csv")
data_1.head(10)

Окончательный результат выглядит так:

Заключение

В этой статье показаны основы использования Beautiful soup в качестве парсера Html для очистки и получения необходимой информации.

Во второй части этой статьи я расскажу, как получать данные из API: « Сбор данных с помощью веб-скрейпинга, веб-сканеров и API (часть 2) ».