Когда Scraping получил HTML с «закодированной» частью, можно ли его получить - PullRequest
1 голос
/ 23 июня 2019

Один из последних шагов в моем проекте - получить цену продукта, я получил все, что мне нужно, кроме цены.

Источник:

<div class="prices">
<div class="price">
    <div class="P01 tooltip"><span>Product 1</span></div>€<div class="encoded" data-price="bzMzlXaZjkxLjUxNA==">151.4</div>
</div>
<div class="price">
    <div class="Po1plus tooltip"><span>Product 1 +</span></div>€<div class="encoded" data-price="MGMSKJDFsTcxLjU0NA==">184.4</div>
</div>

что мне нужно получить после

== ">

Я не знаю, есть ли какая-то защита от закодированной части, но самое короткое, что я получаю, это возвращаю <div class="encoded" data-price="bzMzlXaZjkxLjUxNA=="></div>

Не знаю, уместно ли, я использую "html.parser" для анализа

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

Редактировать: если при разборе теста я не получаю цену, другие методы могут получить его без другого парсера?

EDIT2: это мой код:

page_soup = soup(pagehtml, "html.parser")
pricebox = page_soup.findAll("div",{ "id":"stationList"})
links = pricebox[0].findAll("a",)
det = links[0].findAll("div",)

det[7].text
#or 
det[7].get_text()

результат - ''

Ответы [ 2 ]

2 голосов
/ 23 июня 2019

с регулярным выражением

Полагаю, есть способы сделать это, используя beautifulsoup, в любом случае, здесь есть один подход, использующий regex

import regex

# Assume 'source_code' is the source code posted in the question
prices = regex.findall(r'(?<=data\-price[\=\"\w]+\>)[\d\.]+(?=\<\/div)', source_code)
# ['151.4', '184.4']
# or
[float(p) for p in prices]
# [151.4, 184.4]

Вот краткое объяснение регулярного выражения:

  • [\d\.]+ - это то, что мы на самом деле ищем: \d означает цифры, \. обозначает период, а две цифры, объединенные в квадратных скобках с +, означают, что мы хотим найти хотя бы одну цифру / период
  • Скобки до / после дополнительно указывают, что должно предшествовать / следовать за потенциальным совпадением
  • (?<=data\-price[\=\"\w]+\>) означает, что перед любым потенциальным совпадением должно быть data-price...>, где ... является хотя бы одним из символов A-z0-9="
  • Наконец, (?=\<\/div) означает, что после любого матча должно следовать </div

С lxml

Вот подход с использованием модуля lxml

import lxml.html

tree = lxml.html.fromstring(source_code)
[float(p.text_content()) for p in tree.find_class('encoded')]
# [151.4, 184.4]
1 голос
/ 23 июня 2019

"html.parser" отлично работает как парсер для вашей проблемы. Поскольку вы можете получить это <div class="encoded" data-price="bzMzlXaZjkxLjUxNA=="></div> самостоятельно, это означает, что вам нужны только цены сейчас, и для этого вы можете использовать get_text(), который является встроенной функцией, присутствующей в BeautifulSoup.

Эта функция возвращает любой текст между тегами.

Синтаксис get_text () : tag_name.get_text()

Решение вашей проблемы:

from bs4 import BeautifulSoup

data ='''
<div class="prices">
<div class="price">
    <div class="P01 tooltip"><span>Product 1</span></div>€<div class="encoded" data-price="bzMzlXaZjkxLjUxNA==">151.4</div>
</div>
<div class="price">
    <div class="Po1plus tooltip"><span>Product 1 +</span></div>€<div class="encoded" data-price="MGMSKJDFsTcxLjU0NA==">184.4</div>
</div>
'''

soup = BeautifulSoup(data,"html.parser")

# Searching for all the div tags with class:encoded
a = soup.findAll ('div', {'class' : 'encoded'})

# Using list comprehension to get the price out of the tags
prices = [price.get_text() for price in a]
print(prices)

выход

['151.4', '184.4']

Надеюсь, вы получите то, что ищете. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...