Скрапинг html json в python

Я хочу очистить различные элементы веб-сайта, и у меня есть проблема в определенной части html-кода. Это html-код:

  if ( window.tc_vars ) {
    tc_vars["owner_sub_category"] = ["CENTRE_MULTIMARQUES"];
  }
  var SellerInformationData = {"customerType":"PRO","reference":"E111477039","account":{"familyCode":"CENTRE_MULTIMARQUES","family":"Centre multimarques","address":{"street1":"3 RUE DAGUERRE","city":"RAMBOUILLET","zipCode":"78120","country":"FRANCE","location":{"longitude":1.8492847,"latitude":48.6527683}},"publishedName":"LES GRANDES OCCASIONS.COM RAMBOUILLET","createdDate":"2022-05-30T17:00:03Z"},"companyCreationDate":"2003-04-01","rating":4.75,"feedbackCount":4,"customShowroomUrl":"les-grandes-occasions-rambouillet.espacevo.fr","classifiedsCount":27}

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

script_tag2 = soup.find('script', text=lambda text: text and 'var SellerInformationData' in text)
        json_str2 = script_tag2.text.strip().replace('var SellerInformationData = ', '').replace(';', '')
        datajsSID = json.loads(json_str2)

        try:
            city = datajsSID['account']['address']['city']
        except:
            city = pd.NA

но у меня есть эта ошибка, вы можете мне помочь?

Traceback (most recent call last):
  File "/Users/matheoferrer/PycharmProjects/MemoireM2/main.py", line 257, in <module>
    data = json.loads(json_str)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
json.loads() вызывает эту ошибку, что означает, что что-то не так с вашим парсингом.
Olvin Roght 25.04.2023 15:33

Делаю такой же код для другого элемента в html коде вот так и стоит, почему тут нет? script_tag = soup.find('script', text=lambda text: text and 'var GeneralInformationData' in text) json_str = script_tag.text.strip().replace('var GeneralInformationData = ', '').replace(';', '') datajsGID = json.loads(json_str)

mat47 25.04.2023 15:46

Напечатайте json_str2 перед вызовом json.loads(), и вы увидите, что не так с точной строкой.

Olvin Roght 25.04.2023 15:50

Разве json_str2 все еще не содержит предыдущее if утверждение в этот момент?

JonSG 25.04.2023 15:56

@OlvinRoght печать выводит это,tc_vars["owner_sub_category"] = ["INTERMEDIAIRE"] } {"customerType":"PRO","reference":"W102598229","account":{"f‌​amilyCode":"INTERMED‌​IAIRE","family":"Int‌​ermédiaire","address‌​":{"street1":"12 ROUTE DE BAZAS","city":"LANGON", но если я хочу взять, например, город и поставить это, это не работает city = datajsSID['account']['address']['city']обычно это правильные теги для доступа к городу, но ничего не работает

mat47 25.04.2023 16:11

@JonSG нет if, мне его куда-нибудь положить?

mat47 25.04.2023 16:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
6
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша проблема в том, что ваш soup.find() получает весь тег, а не только строку, которая активировала фильтр.

Например:

from bs4 import BeautifulSoup

html = """
<script>
  if ( window.tc_vars ) {
    tc_vars["owner_sub_category"] = ["CENTRE_MULTIMARQUES"];
  }
  var SellerInformationData = {"customerType":"PRO","reference":"E111477039","account":{"familyCode":"CENTRE_MULTIMARQUES","family":"Centre multimarques","address":{"street1":"3 RUE DAGUERRE","city":"RAMBOUILLET","zipCode":"78120","country":"FRANCE","location":{"longitude":1.8492847,"latitude":48.6527683}},"publishedName":"LES GRANDES OCCASIONS.COM RAMBOUILLET","createdDate":"2022-05-30T17:00:03Z"},"companyCreationDate":"2003-04-01","rating":4.75,"feedbackCount":4,"customShowroomUrl":"les-grandes-occasions-rambouillet.espacevo.fr","classifiedsCount":27}
</script>
"""

soup = BeautifulSoup(html, 'html.parser')
script_tag2 = soup.find('script', text=lambda text: text and 'var SellerInformationData' in text)

print(script_tag2)

Дам тебе:

  if ( window.tc_vars ) {
    tc_vars["owner_sub_category"] = ["CENTRE_MULTIMARQUES"];
  }
  var SellerInformationData = {"customerType":"PRO","reference":"E111477039","account":{"familyCode":"CENTRE_MULTIMARQUES","family":"Centre multimarques","address":{"street1":"3 RUE DAGUERRE","city":"RAMBOUILLET","zipCode":"78120","country":"FRANCE","location":{"longitude":1.8492847,"latitude":48.6527683}},"publishedName":"LES GRANDES OCCASIONS.COM RAMBOUILLET","createdDate":"2022-05-30T17:00:03Z"},"companyCreationDate":"2003-04-01","rating":4.75,"feedbackCount":4,"customShowroomUrl":"les-grandes-occasions-rambouillet.espacevo.fr","classifiedsCount":27}

Когда вы replace('var SellerInformationData = ', ''), вы все еще остаетесь с утверждением if.

if ( window.tc_vars ) {
    tc_vars["owner_sub_category"] = ["CENTRE_MULTIMARQUES"]
  }
  {"customerType":"PRO","reference":"E111477039","account":{"familyCode":"CENTRE_MULTIMARQUES","family":"Centre multimarques","address":{"street1":"3 RUE DAGUERRE","city":"RAMBOUILLET","zipCode":"78120","country":"FRANCE","location":{"longitude":1.8492847,"latitude":48.6527683}},"publishedName":"LES GRANDES OCCASIONS.COM RAMBOUILLET","createdDate":"2022-05-30T17:00:03Z"},"companyCreationDate":"2003-04-01","rating":4.75,"feedbackCount":4,"customShowroomUrl":"les-grandes-occasions-rambouillet.espacevo.fr","classifiedsCount":27}

Что, конечно, недопустимо json.

Вам нужно выбрать эту строку либо чем-то вроде пакета re, либо вручную, проверив строку этого блока скрипта. Пытаться:

import json
from bs4 import BeautifulSoup

html = """
<script>
  if ( window.tc_vars ) {
    tc_vars["owner_sub_category"] = ["CENTRE_MULTIMARQUES"];
  }
  var SellerInformationData = {"customerType":"PRO","reference":"E111477039","account":{"familyCode":"CENTRE_MULTIMARQUES","family":"Centre multimarques","address":{"street1":"3 RUE DAGUERRE","city":"RAMBOUILLET","zipCode":"78120","country":"FRANCE","location":{"longitude":1.8492847,"latitude":48.6527683}},"publishedName":"LES GRANDES OCCASIONS.COM RAMBOUILLET","createdDate":"2022-05-30T17:00:03Z"},"companyCreationDate":"2003-04-01","rating":4.75,"feedbackCount":4,"customShowroomUrl":"les-grandes-occasions-rambouillet.espacevo.fr","classifiedsCount":27}
</script>
"""

prefix = "var SellerInformationData = "
suffix = ";"

soup = BeautifulSoup(html, 'html.parser')
script_tag2 = soup.find('script', text=lambda text: text and prefix in text)

datajsSID = {}
for line in script_tag2.text.split("\n"):
    line = line.strip()
    if line.startswith(prefix):
        line = line.removeprefix(prefix).removesuffix(suffix)
        datajsSID = json.loads(line)
        break

city = datajsSID.get("account",{}).get("address",{}).get("city")
print(f"City: {city}")

rating = datajsSID.get("rating")
print(f"Rating: {rating}")

Это должно дать вам:

City: RAMBOUILLET
Rating: 4.75

Спасибо большое работает отлично. Так же небольшой вопросик вдобавок иметь "рейтинг" например код не работает. Есть ли что-то конкретное, что нужно изменить?

mat47 25.04.2023 17:59

рейтинг просто на другом пути rating = datajsSID.get("rating")

JonSG 25.04.2023 18:03

Да, но результат "Нет", когда я это делаю

mat47 25.04.2023 18:08

не тогда, когда я это делаю ... сейчас я обновлю свой ответ

JonSG 25.04.2023 18:09

Странно, я делаю то же самое, и у меня ничего нет. Но ничего, попробую найти, еще раз спасибо

mat47 25.04.2023 18:25

эти данные присутствуют в другом месте страницы и выглядят следующим образом: ``` if (window.tc_vars) { tc_vars["rating_satisfaction"] = 4.75; tc_vars["rating_count"] = 4; } ``` и я безуспешно пробовал ``` script_tag_regex = r'<script>window\.tc_vars = window\.tc_vars \|\| [](.*?)</script>' script_tag = re.findall(script_tag_regex, response.text, re.DOTALL)[0] rating_regex = r'tc_vars["rating_satisfaction"] = (.*?);' rating = re.findall(rating_regex, script_tag)[0] ``` Что вы думаете?

mat47 25.04.2023 18:46

та же стратегия должна работать с prefix = "tc_vars[\"rating_satisfaction\"] = "

JonSG 25.04.2023 18:56

Другие вопросы по теме