У меня есть фрагмент HTML, который я извлек с помощью BeautifulSoup, который содержит путь SVG и заголовок.
Мне интересно, есть ли способ извлечь текст заголовка и координаты из этого фрагмента.
<g class = "myclass"><title>mytitle</title><path d = "M -5, 0 a 5,5 0 1,0 10,0 a 5,5 0 1,0 -10,0" fill = "rgba(255,255,255, 0.1" stroke = "rgba(10, 158, 117, 0.8)" stroke-width = "3" transform = "translate(178.00000000000003, 201)"></path></g>
Ниже приведена функция, которая возвращает указанный выше фрагмент (rows).
def scrape_spatial_data(page):
html = page.inner_html("body")
soup = BeautifulSoup(html, "html.parser")
rows = soup.select("g.myclass")
return rows
Есть ли более чистый способ извлечь это с помощью BeautifulSoup?
Страница @SIGHUP — это объект драматурга. URL-адрес, которым я не могу поделиться, поскольку он частный. browser = p.chromium.launch(headless=False)context = browser.new_context()page = context.new_page()page.goto(the_url)
Какой именно результат вы ожидаете? Под «координатами» вы имеете в виду значения в translate() или значение d=?






Разумным подходом к этому было бы вернуть словарь, который основан на именах атрибутов (из тега пути) и заголовке.
Я рекомендую использовать lxml (если он доступен) в качестве анализатора HTML для повышения производительности.
Попробуй это:
from playwright.sync_api import Page
from bs4 import BeautifulSoup as BS
from functools import cache
@cache
def get_parser():
try:
import lxml
return "lxml"
except Exception:
pass
return "html.parser"
def scrape_spatial_data(page: Page) -> dict[str, str]:
html = page.inner_html("body")
soup = BS(html, get_parser())
result = {}
if row := soup.select_one("g.myclass"):
if t := row.select_one("title"):
result["title"] = t.text
if p := row.select_one("path"):
result.update(p.attrs)
return result
Для данных, показанных в вопросе, это покажет:
{
"title": "mytitle",
"d": "M -5, 0 a 5,5 0 1,0 10,0 a 5,5 0 1,0 -10,0",
"fill": "rgba(255,255,255, 0.1",
"stroke": "rgba(10, 158, 117, 0.8)",
"stroke-width": "3",
"transform": "translate(178.00000000000003, 201)"
}
У Playwright уже есть мощный API определения местоположения, который автоматически ожидает и работает на живой странице. Передача HTML-снимка страницы в BeautifulSoup только для того, чтобы сделать выбор, кажется ненужной, как покупка велосипеда только для того, чтобы кататься на нем, а не кататься на нем. С другой стороны, если HTML-код OP можно запрашивать статически, я бы не использовал Playwright, а вместо этого использовал бы requests для получения HTML-кода страницы без автоматизации браузера.
@ggorlen Справедливый комментарий, но имейте в виду, в чем вопрос. BeautifulSoup вполне может быть неподходящим, но это (по-видимому) то, что требуется. Наше дело не в том, чтобы рассуждать, почему
Люди постоянно задают проблемы XY, и будущим посетителям, а также ОП, будет оказана медвежья услуга, если не упомянуть хотя бы о том, что может быть лучший способ сделать то, чего они хотят достичь. В любом случае, если вопрос о BS, то «Драматург» кажется лишним — одна или другая — я использую обе технологии уже много лет и никогда не видел варианта их объединения. Обычно это делают новички, не знакомые с библиотеками.
@ggorlen 100%, я действительно новичок в обеих библиотеках - таблица, из которой я собираю данные, имеет кнопку «следующая страница», которую я использую драматург для навигации, а затем BS для моментального снимка этих данных. Если есть способ сделать то же самое в драматурге без использования BS, я бы хотел научиться
Если вы используете Playwright, нет необходимости использовать BeautifulSoup: выгрузка живого DOM в строку только для передачи в BS является антишаблоном и подвержена ошибкам. У Playwright есть полный набор локаторов и селекторов, которые работают с живой DOM и даже автоматически ждут действия перед операцией.
Итак, предполагая, что вы автоматизируете одностраничное приложение, избавьте себя от зависимостей, дополнительного синтаксиса, снижения производительности и потенциальных ошибок и придерживайтесь локаторов во всем:
from playwright.sync_api import sync_playwright # 1.44.0
svg = """<Your example SVG from the question, verbatim>"""
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.set_content(svg) # for demonstration, normally use goto
title = page.locator(".myclass title").text_content()
coordinates = page.locator(".myclass path").get_attribute("transform")
print(title, coordinates)
browser.close()
Если вы хотите извлечь значения из аргументов translate(), вы можете использовать:
x, y = [float(x) for x in re.findall(r"[\d.]+", coordinates)]
Если вам нужны все атрибуты из элемента пути, вы можете использовать JS в браузере:
attrs = page.locator(".myclass path").evaluate("""
el => Object.fromEntries([...el.attributes].map(e => [e.name, e.value]))
""")
С другой стороны, если вы очищаете статическую HTML-страницу, рассмотрите возможность отказа от Playwright в пользу запросов + BeautifulSoup.
Спасибо - попробую. Желание получить максимальную производительность, поэтому это будет полезно. Страница представляет собой динамическую HTML-страницу, поэтому, я думаю, понадобится драматург.
Что такое страница? Кроме того, если веб-сайт является общедоступным, сообщите его URL-адрес и код, который вы используете для доступа к нему.