CoderCastrov logo
CoderCastrov
Xpath - Парсер

Парсинг веб-страниц с использованием Python и Beautifulsoup часть 2

Парсинг веб-страниц с использованием Python и Beautifulsoup часть 2
просмотров
5 мин чтение
#Xpath - Парсер

Парсинг веб-страниц с использованием дополнительных функций и библиотек

Мы уже обсудили основы парсинга веб-страниц в предыдущей части, если вы новичок, то я рекомендую вам сначала прочитать часть 1.

Парсинг веб-страниц с использованием Python и BeautifulSoup часть 1

Как парсить контент с использованием Python на любом веб-сайте (основы)

medium.com

В этой статье мы попробуем изучить несколько продвинутых функций BeautifulSoup и различные способы поиска на страницах. В предыдущей части у нас был сайт для парсинга - yellow-pages.ph, где исходный код очень понятный и легко найти идентификатор тега. Здесь я имею в виду, что каждый тег имеет класс, но что произойдет, если в этом конкретном теге, который мы хотим спарсить, нет класса или возможно есть другой способ идентификации этого тега? В такой ситуации, как мы можем использовать функцию find или find_all, или другую технику для поиска контекста страницы? BeautifulSoup - хорошая библиотека для парсинга, но мы также можем использовать XPATH, регулярные выражения (regex), мы также можем использовать pandas, но только в случае таблиц. Давайте попробуем каждую функцию по очереди.

Давайте начнем

сначала мы попробуем изучить функции BeautifulSoup для этой статьи, у меня есть URL https://www.worldometers.info/world-population/, который сообщает нам о населении мира, поэтому здесь мы собираем различные контексты. На этой странице есть несколько таблиц, которые содержат информацию о населении, одна из них приведена ниже

source: worldometers.info/world-population

сначала мы собираем данные таблицы с помощью функции BeautifulSoup. Мы уже знаем, что таблица в HTML создается с помощью тега <table>, а внутри тега <table> у нас есть два тега <tr> (строки таблицы) и <td> (данные таблицы). Итак, здесь сначала идет тег <table>, а затем внутренний тег

если вы проверите код всех таблиц, то обнаружите, что имя класса одинаково для каждого тега таблицы, если мы найдем его с помощью тега/имени класса, то ответ не будет соответствовать требуемой таблице, поэтому вопрос здесь - можно ли найти тег с помощью их атрибутов (id, name, value и т. д.), а не класса, ответ - да, на рисунке ниже таблица имеет атрибут id, здесь мы найдем тег с помощью id, в большинстве случаев класс дублируется на странице, но в случае с id он не может быть дублирован на всей странице

inspect element of worldometers page

Наш тег имеет имя таблицы, а атрибут - это id, мы можем использовать как find, так и find_all для атрибутов, он принимает дополнительный параметр attrs, который является словарем атрибутов.

давайте напишем код

import requests
from bs4 import BeautifulSoup as BS
r = requests.get("https://www.worldometers.info/world-population/")
soup = BS(r.content,'html.parser')

во всей статье мы будем использовать вышеуказанный блок soup.

находим тег по id

table = soup.find("table",attrs={"id":"popbycountry"})#now find tr and td tags in tabletr = table.find_all("tr")
for i in tr:
    for td in i.find_all("td"):
        print(td.text,end = "\t")  #it just for print
    print()# this code print this table in console

output in my console

круто, очень легко вывести на консоль, мы могли бы сохранить его в любой файл или базу данных. еще одна вещь в таблицах, как мы видели, данные таблицы обрабатываются в теге таблицы, но не все веб-сайты помещают свой код в тег таблицы, веб-сайты могут использовать тег div или article для создания таблицы, поэтому сначала прочитайте тег таблицы данных, а затем собирайте данные.

Pandas для таблицы

Вы знаете, что pandas также отличная библиотека, специализированная для работы с таблицами? Тогда вопрос в том, можно ли использовать pandas для парсинга таблиц? Ответ - ДА, и это делает процесс еще проще. В pandas нам даже не нужно искать теги таблицы на веб-странице, он ищет все таблицы в виде DataFrame и сохраняет их в список (я не буду здесь обсуждать DataFrame).

import pandas as pd
import requests
r = requests.get("https://www.worldometers.info/world-population/")
tables = pd.read_html(r.text)
print(tables[4]) # пятая таблица

Ссылка, которую мы запросили на worldometers, содержит 5 таблиц, затем все таблицы сохраняются в переменной tables, теперь очень легко выполнять вычисления с помощью DataFrame и сохранять их в CSV, JSON или SQL.

Регулярные выражения (регулярные выражения)

Регулярные выражения обычно используются для поиска последовательностей и шаблонов символов, а также играют важную роль в парсинге. Это встроенная библиотека для Python, и для сопоставления и поиска не требуется использовать классы или теги, у него есть собственные правила для определения шаблонов. В этой статье я не буду использовать все методы. Давайте посмотрим, как это работает!

Например, на странице worldometers нам нужно узнать население Индии. Если вы проверите, то там нет специального класса или тега для этого, страна находится в теге с атрибутом href, в таком случае мы можем использовать регулярные выражения.

import re
india_population = re.findall('India</a></td> <td style="font-weight: bold;">(.*?)</td>', r.text)
print(india_population)

Это немного сложно, но если мы попрактикуемся 4-5 раз, то кажется очень простым.

XPATH

XPath (язык пути XML) позволяет обходить страницу по узлам, HTML-страница содержит структуру тегов, которые можно назвать узлами. XPath похож на Beautifulsoup, но имеет большую производительность. Для работы с XPath необходимо установить lxml через pip. Давайте посмотрим, как это работает.

У нас есть еще один веб-сайт для парсинга - https://indiamart.com. На этом веб-сайте мы будем парсить названия продуктов с использованием XPath. Я искал обувь и получил список с URL-адресом https://dir.indiamart.com/search.mp?ss=shoes.

from lxml import html
import requests
r = requests.get("https://dir.indiamart.com/search.mp?ss=shoes")
tree = html.fromstring(r.text)

Поиск XPath в тегах начинается с //, а поиск атрибутов и текста начинается с /. Синтаксис для XPath выглядит так: tree.xpath('//tagName[@attribue=“value”]/text()'). Он возвращает список текстовых результатов.

На изображении выше тег - <a> с атрибутом class, поэтому наш запрос будет выглядеть так:

names = tree.xpath('//a[@class=“fs18 ptitle”]/text()')
print(names)

Отлично! Звучит просто. У нас есть все названия без необходимости использования цикла, как в BeautifulSoup. Но что насчет атрибутов? Для текста мы просто добавляем /text() в конец запроса, а для атрибута мы добавляем имя атрибута с /@attribute. Например, если мы хотим спарсить все ссылки (href) из тега, то запрос будет таким:

links = tree.xpath('//a[@class="fs18 ptitle"]/@href')

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

Спасибо за чтение....