Извлечение текста из json внутри тега <script>при наличии нескольких jsons - PullRequest
0 голосов
/ 04 февраля 2019

Я пытаюсь извлечь рейтинг из https://www.truthorfiction.com/are-americans-annually-healthcare-undocumented/, чтобы извлечь поля "ratingValue" и "alternateName" из кода HTML:

<script type=application/ld+json>{
"@context": "http://schema.org",
"@type": "ClaimReview",
"datePublished": "2019-01-03 ",
"url": "https://www.truthorfiction.com/are-americans-annually-healthcare-undocumented/",
"author": {
    "@type": "Organization",
    "url": "https://www.truthorfiction.com/",
    "image": "https://dn.truthorfiction.com/wp-content/uploads/2018/10/25032229/truth-or-fiction-logo-tagline.png",
    "sameAs": "https://twitter.com/whatstruecom"
},
"claimReviewed": "More Americans die every year from a lack of affordable healthcare than by terrorism or at the hands of undocumented immigrants.",
"reviewRating": {
    "@type": "Rating",
    "ratingValue": -1,
    "worstRating":-1,
    "bestRating": -1,
    "alternateName": "True"
},
    "itemReviewed": {
    "@type": "CreativeWork",
    "author": {
        "@type": "Person",
        "name": "Person",
        "jobTitle": "",
        "image": "",
        "sameAs": [
            ""
        ]
    },
    "datePublished": "",
    "name": ""
}
}</script>

Я пытался это сделатьиспользуя следующий код:

import json
from bs4 import BeautifulSoup

slink = 'https://www.truthorfiction.com/are-americans-annually-healthcare-undocumented/'
response = http.request('GET', slink)
soup = BeautifulSoup(response.data)
tmp = json.loads(soup.find('script', type='application/ld+json').text)

Однако вместо этого tmp показывает словарь элемента application / ld + json из бита, предшествующего рейтингу, который я хотел бы извлечь, и мне было интересно, какцикл или цикл до соответствующей части скрипта, где хранятся рейтинги.

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

имеет 2 <script type=application/ld+json>, вы можете выбрать второй индекс из find_all()

tmp = json.loads(soup.find_all('script', type='application/ld+json')[1].text)

или выполнить цикл и выполнить поиск, если он содержит строку

tmp = None
for ldjson in soup.find_all('script', type='application/ld+json'):
    if 'ratingValue' in ldjson.text:
        tmp = json.loads(ldjson.text)
0 голосов
/ 04 февраля 2019

Вам необходимо получить доступ к элементу с помощью клавиш.

rating_value = tmp['reviewRating']['ratingValue'] # -1
alternate_name = tmp['reviewRating']['alternateName'] # 'True'

или

review_rating = tmp['reviewRating']
rating_value = review_rating['ratingValue'] # -1
alternate_name = review_rating['alternateName'] # 'True'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...