Предположим, вы хотите получить информацию с веб-сайта? Скажем, статья с сайта geeksforgeeks или новость, что вы будете делать? Первое, что может прийти вам в голову, — это скопировать и вставить информацию на ваш местный носитель. Но что, если вам нужен большой объем данных ежедневно и как можно быстрее. В таких ситуациях копирование и вставка не работают, и именно здесь вам понадобится веб-скрейпинг.
В этой статье мы обсудим, как выполнять парсинг веб-страниц с помощью библиотеки запросов и библиотеки beautifulsoup в Python.
Модуль запросов
Библиотека запросов используется для выполнения HTTP-запросов к определенному URL-адресу и возвращает ответ. Запросы Python предоставляют встроенные функции для управления как запросом, так и ответом.
Установка
Установка запросов зависит от типа операционной системы, основная команда в любом месте — открыть командный терминал и запустить,
pip install requests
Сделать запрос
Модуль запросов Python имеет несколько встроенных методов для выполнения HTTP-запросов к указанному URI с использованием запросов GET, POST, PUT, PATCH или HEAD. HTTP-запрос предназначен либо для получения данных из указанного URI, либо для отправки данных на сервер. Он работает как протокол запроса-ответа между клиентом и сервером. Здесь мы будем использовать запрос GET.
Метод GET используется для получения информации с заданного сервера с использованием заданного URI. Метод GET отправляет закодированную информацию о пользователе, добавленную к запросу страницы.
Пример: запросы Python, выполняющие запрос GET
Python3
import
requests
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# check status code for response received
# success code - 200
(r)
# print content of request
(r.content)
Вывод:
Объект ответа
Когда кто-то делает запрос к URI, он возвращает ответ. Этот объект Response в терминах python возвращается с помощью request.method (), являющегося методом — get, post, put и т.д. Response — это мощный объект с множеством функций и атрибутов, которые помогают в нормализации данных или создании идеальных частей кода. Например, response.status_code возвращает код состояния из самих заголовков, и можно проверить, был ли запрос обработан успешно или нет.
Объекты ответа могут использоваться для обозначения множества функций, методов и функций.
Пример: Python запрашивает объект ответа
Python3
import
requests
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# print request object
(r.url)
# print status code
(r.status_code)
Вывод:
https://www.geeksforgeeks.org/python-programming-language/ 200
Библиотека BeautifulSoup
BeautifulSoup используется для извлечения информации из файлов HTML и XML. Он предоставляет дерево синтаксического анализа и функции для навигации, поиска или изменения этого дерева синтаксического анализа.
Установка
Чтобы установить Beautifulsoup в Windows, Linux или любой другой операционной системе, потребуется пакет pip. Чтобы узнать, как установить pip в вашей операционной системе, посмотрите — Установка PIP — Windows || Linux. Теперь запустите следующую команду в терминале.
pip install beautifulsoup4
Проверка веб-сайта
Прежде чем извлекать какую-либо информацию из HTML страницы, мы должны понять структуру страницы. Это нужно сделать для того, чтобы выделить нужные данные со всей страницы. Мы можем сделать это, щелкнув правой кнопкой мыши страницу, которую мы хотим очистить, и выбрав элемент проверки.
После нажатия кнопки проверки откроются инструменты разработчика браузера. Теперь почти все браузеры поставляются с установленными инструментами разработчика, и в этом руководстве мы будем использовать Chrome.
Инструменты разработчика позволяют увидеть объектную модель документа (DOM) сайта. Если вы не знаете о DOM, не беспокойтесь, просто рассмотрите отображаемый текст как HTML-структуру страницы.
Разбор HTML
После получения HTML-кода страницы давайте посмотрим, как проанализировать этот необработанный HTML-код и получить полезную информацию. Прежде всего, мы создадим объект BeautifulSoup, указав парсер, который мы хотим использовать.
Примечание. Библиотека BeautifulSoup построена на основе библиотек синтаксического анализа HTML, таких как html5lib, lxml, html.parser и т. Д. Таким образом, объект BeautifulSoup и указанная библиотека синтаксического анализатора могут быть созданы одновременно.
Пример: Python BeautifulSoup анализирует HTML
Python3
import
requests
from
bs4
import
BeautifulSoup
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# check status code for response received
# success code - 200
(r)
# Parsing the HTML
soup
=
BeautifulSoup(r.content,
'html.parser'
)
(soup.prettify())
Вывод:
Эта информация для нас все еще не полезна, давайте посмотрим на другой пример, чтобы сделать из этого некоторую ясную картину. Попробуем извлечь заголовок страницы.
Python3
import
requests
from
bs4
import
BeautifulSoup
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# Parsing the HTML
soup
=
BeautifulSoup(r.content,
'html.parser'
)
# Getting the title tag
(soup.title)
# Getting the name of the tag
(soup.title.name)
# Getting the name of parent tag
(soup.title.parent.name)
# use the child attribute to get
# the name of the child tag
Вывод:
<title>Python Programming Language - GeeksforGeeks</title> title html
Поиск элементов
Теперь мы хотели бы извлечь некоторые полезные данные из содержимого HTML. Объект soup содержит все данные во вложенной структуре, которые могут быть извлечены программно. Веб-сайт, который мы хотим очистить, содержит много текста, поэтому теперь давайте очистим весь этот контент. Во-первых, давайте проверим веб-страницу, которую мы хотим очистить.
Поиск элементов по классу
На изображении выше мы видим, что все содержимое страницы находится под блоком div с классом entry-content. Мы будем использовать класс find. Этот класс найдет данный тег с данным атрибутом. В нашем случае он найдет весь div, имеющий class как entry-content. У нас есть весь контент с сайта, но вы можете видеть, что все изображения и ссылки также очищены. Итак, наша следующая задача — найти только контент из проанализированного выше HTML. При повторном просмотре HTML-кода нашего веб-сайта —
Мы видим, что содержимое страницы находится под тегом <p>. Теперь нам нужно найти все теги p, присутствующие в этом классе. Мы можем использовать класс find_all в BeautifulSoup.
Python3
import
requests
from
bs4
import
BeautifulSoup
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# Parsing the HTML
soup
=
BeautifulSoup(r.content,
'html.parser'
)
s
=
soup.find(
'div'
,
class_
=
'entry-content'
)
content
=
s.find_all(
'p'
)
(content)
Вывод:
Поиск элементов по идентификатору
В приведенном выше примере мы нашли элементы по имени класса, но давайте посмотрим, как найти элементы по идентификатору. Теперь для этой задачи давайте очистим содержимое левой панели страницы. Первый шаг — проверить страницу и увидеть, под какой тег находится левая панель.
На изображении выше показано, что левая панель находится под тегом <div> с id в качестве основного. Теперь давайте возьмем HTML-контент под этим тегом. Теперь давайте посмотрим на большую часть страницы, чтобы получить содержимое левой панели.
Мы видим, что список на левой панели находится под тегом <ul> с классом leftBarList, и наша задача — найти все li под этим ul.
Python3
import
requests
from
bs4
import
BeautifulSoup
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# Parsing the HTML
soup
=
BeautifulSoup(r.content,
'html.parser'
)
# Finding by id
s
=
soup.find(
'div'
,
id
=
'main'
)
# Getting the leftbar
leftbar
=
s.find(
'ul'
,
class_
=
'leftBarList'
)
# All the li under the above ul
content
=
leftbar.find_all(
'li'
)
(content)
Вывод:
Извлечение текста из тегов
В приведенных выше примерах вы, должно быть, видели, что при очистке данных теги также очищаются, но что, если нам нужен только текст без каких-либо тегов. Не волнуйтесь, мы обсудим то же самое в этом разделе. Мы будем использовать свойство text. Он печатает только текст из тега. Мы будем использовать приведенный выше пример и удалим из них все теги.
Пример 1. Удаление тегов из содержимого страницы
Python3
import
requests
from
bs4
import
BeautifulSoup
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# Parsing the HTML
soup
=
BeautifulSoup(r.content,
'html.parser'
)
s
=
soup.find(
'div'
,
class_
=
'entry-content'
)
lines
=
s.find_all(
'p'
)
for
line
in
lines:
(line.text)
Вывод:
Пример 2: Удаление тегов из содержимого левой панели
Python3
import
requests
from
bs4
import
BeautifulSoup
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# Parsing the HTML
soup
=
BeautifulSoup(r.content,
'html.parser'
)
# Finding by id
s
=
soup.find(
'div'
,
id
=
'main'
)
# Getting the leftbar
leftbar
=
s.find(
'ul'
,
class_
=
'leftBarList'
)
# All the li under the above ul
lines
=
leftbar.find_all(
'li'
)
for
line
in
lines:
(line.text)
Вывод:
Извлечение ссылок
До сих пор мы видели, как извлекать текст, теперь давайте посмотрим, как извлекать ссылки со страницы.
Пример: Python BeatifulSoup извлекает ссылки
Python3
import
requests
from
bs4
import
BeautifulSoup
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# Parsing the HTML
soup
=
BeautifulSoup(r.content,
'html.parser'
)
# find all the anchor tags with "href"
for
link
in
soup.find_all(
'a'
):
(link.get(
'href'
))
Вывод:
Извлечение информации об изображении
При повторном просмотре страницы мы видим, что изображения лежат внутри тега img, а ссылка на это изображение находится внутри атрибута src. См. Изображение ниже —
Пример: Python BeautifulSoup Extract Image
Python3
import
requests
from
bs4
import
BeautifulSoup
# Making a GET request
r
=
requests.get(
'https://www.geeksforgeeks.org/python-programming-language/'
)
# Parsing the HTML
soup
=
BeautifulSoup(r.content,
'html.parser'
)
images_list
=
[]
images
=
soup.select(
'img'
)
for
image
in
images:
src
=
image.get(
'src'
)
alt
=
image.get(
'alt'
)
images_list.append({
"src"
: src,
"alt"
: alt})
for
image
in
images_list:
(image)
Вывод:
Очистка нескольких страниц
Теперь могут возникнуть различные случаи, когда вы можете захотеть получить данные с нескольких страниц с одного и того же веб-сайта или с нескольких разных URL-адресов, а вручную написать код для каждой веб-страницы — трудоемкая и утомительная задача. Кроме того, это противоречит всем основным принципам автоматизации. Ага!
Чтобы решить эту точную проблему, мы увидим два основных метода, которые помогут нам извлекать данные с нескольких веб-страниц:
- Тот же сайт
- Различные URL-адреса веб-сайтов
Пример 1: переход по номерам страниц
номера страниц внизу сайта GeeksforGeeks
Большинство веб-сайтов имеют страницы, помеченные от 1 до N. Это позволяет нам очень просто просматривать эти страницы и извлекать из них данные, поскольку эти страницы имеют схожую структуру. Например:
номера страниц внизу сайта GeeksforGeeks
Здесь мы можем видеть детали страницы в конце URL-адреса. Используя эту информацию, мы можем легко создать цикл for, перебирающий столько страниц, сколько захотим (поместив page / (i) / в строку URL и повторяя «i» до N), и очистить от них все полезные данные. Следующий код прояснит, как очищать данные с помощью цикла For Loop в Python.
Python3
import
requests
from
bs4
import
BeautifulSoup as bs
URL
=
'https://www.geeksforgeeks.org/page/1/'
req
=
requests.get(URL)
soup
=
bs(req.text,
'html.parser'
)
titles
=
soup.find_all(
'div'
,attrs
=
{
'class'
,
'head'
})
(titles[
4
].text)
Вывод:
7 самых распространенных потерь времени при разработке программного обеспечения
Теперь, используя приведенный выше код, мы можем получить заголовки всех статей, просто поместив эти строки в цикл.
Python3
import
requests
from
bs4
import
BeautifulSoup as bs
URL
=
'https://www.geeksforgeeks.org/page/'
for
page
in
range
(
1
,
10
):
req
=
requests.get(URL
+
str
(page)
+
'/'
)
soup
=
bs(req.text,
'html.parser'
)
titles
=
soup.find_all(
'div'
, attrs
=
{
'class'
,
'head'
})
for
i
in
range
(
4
,
19
):
if
page >
1
:
(f
"{(i-3)+page*15}"
+
titles[i].text)
else
:
(f
"{i-3}"
+
titles[i].text)
Вывод:
Пример 2: просмотр списка разных URL-адресов
Вышеупомянутый метод абсолютно замечателен, но что, если вам нужно очистить разные страницы, и вы не знаете их номера? Вам нужно будет очистить эти разные URL-адреса один за другим и вручную написать сценарий для каждой такой веб-страницы.
Вместо этого вы можете просто составить список этих URL-адресов и просмотреть их в цикле. Просто перебирая элементы в списке, то есть URL-адреса, мы сможем извлекать заголовки этих страниц без необходимости писать код для каждой страницы. Вот пример кода, как это можно сделать.
Python3
import
requests
from
bs4
import
BeautifulSoup as bs
URL
=
[
'https://www.geeksforgeeks.org'
,
'https://www.geeksforgeeks.org/page/10/'
]
for
url
in
range
(
0
,
2
):
req
=
requests.get(URL[url])
soup
=
bs(req.text,
'html.parser'
)
titles
=
soup.find_all(
'div'
,attrs
=
{
'class'
,
'head'
})
for
i
in
range
(
4
,
19
):
if
url
+
1
>
1
:
(f
"{(i - 3) + url * 15}"
+
titles[i].text)
else
:
(f
"{i - 3}"
+
titles[i].text)
Вывод:
Для получения дополнительной информации см. Наше руководство по Python BeautifulSoup.
Сохранение данных в CSV
Сначала мы создадим список словарей с парами ключ-значение, которые мы хотим добавить в файл CSV. Затем мы будем использовать модуль csv для записи вывода в файл CSV. См. Пример ниже для лучшего понимания.
Пример: сохранение Python BeautifulSoup в CSV
Python3
import
requests
from
bs4
import
BeautifulSoup as bs
import
csv
URL
=
'https://www.geeksforgeeks.org/page/'
soup
=
bs(req.text,
'html.parser'
)
titles
=
soup.find_all(
'div'
, attrs
=
{
'class'
,
'head'
})
titles_list
=
[]
count
=
1
for
title
in
titles:
d
=
{}
d[
'Title Number'
]
=
f
'Title {count}'
d[
'Title Name'
]
=
title.text
count
+
=
1
titles_list.append(d)
filename
=
'titles.csv'
with
open
(filename,
'w'
, newline
=
'') as f:
w
=
csv.DictWriter(f,[
'Title Number'
,
'Title Name'
])
w.writeheader()
w.writerows(titles_list)
Вывод: