Работа с интерполированными значениями в веб-очистке (Beautiful Soup)

#python #web-scraping #beautifulsoup

#python #веб-очистка #beautifulsoup

Вопрос:

Я выполняю некоторую веб-очистку с помощью Python и Beautiful Soup.

Я столкнулся с проблемой, когда результаты, которые я получаю, содержат необработанные интерполяции Javascript, а не сами значения.

Итак, вместо

<span>2.4%</span>

который я вижу в инспекторе Chrome, я вместо этого получаю:

<span> {{ item.rate }} </span>

с моим результатом из beautiful soup.

a) Я делаю что-то неправильно (аналогичный код работает на другом веб-сайте, поэтому я так не думаю, но могу ошибаться)?

или

б) Есть ли способ справиться с этим?

Мой код:

 url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
divs = soup.findAll("ul", {"class": "result-table--grid"})
print(div[0])
  

Спасибо!

Комментарии:

1. я предполагаю, что страница динамическая. Это значение может храниться в тегах скрипта или, возможно, может быть доступно через URL-адрес запроса api. возможно ли поделиться URL-адресом?

2. Ага, имеет смысл. URL -адрес является moneysupermarket.com/mortgages/results /…

3. Ниже я предоставил код для извлечения этих данных. Другой вариант заключается в том, что вы также можете использовать Selenium для первого рендеринга страницы, а ЗАТЕМ извлечь исходный код html, как вы уже делаете.

Ответ №1:

Вы можете получить доступ к ответу в формате json следующим образом ниже. затем использование json_normalize . Теперь, сделав это, вы увидите, что в столбцах есть следующие списки / словари. Итак, я предложу второе решение, которое также сглаживает их, но оно действительно расширит вашу таблицу по горизонтали

Код 1

 import requests
from bs4 import BeautifulSoup
from pandas.io.json import json_normalize
import pandas as pd

url = "https://www.moneysupermarket.com/mortgages/results/#?goal=1amp;property=170000amp;borrow=150000amp;types=1amp;types=2amp;types=3amp;types=4amp;types=5"

request_url = 'https://www.moneysupermarket.com/bin/services/aggregation'

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'}

payload = {
'channelId': '55',
'enquiryId': '2e619c17-061a-4812-adad-40a9f9d8dcbc',
'limit': '20',
'offset': '0',
'sort': 'initialMonthlyPayment'}


jsonObj = requests.get(request_url, headers=headers, params = payload).json()

results = pd.DataFrame()
for each in jsonObj['results']:
    temp_df = json_normalize(each['quote'])
    results = results.append(temp_df).reset_index(drop=True)
  

Вывод 1:

 print (results)
                                               @class                        ...                                                         trackerDescription
0   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
1   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
2   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
3   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
4   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
5   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
6   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
7   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
8   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
9   com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
10  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
11  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
12  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
13  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
14  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
15  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                          after 26 Months,BBR   3.99% for the remaining ...
16  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
17  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
18  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                                                                           
19  com.moneysupermarket.mortgages.entity.Mortgage...                        ...                          after 26 Months,BBR   3.99% for the remaining ...

[20 rows x 51 columns]
  

Код 2:

 import requests
import pandas as pd

url = "https://www.moneysupermarket.com/mortgages/results/#?goal=1amp;property=170000amp;borrow=150000amp;types=1amp;types=2amp;types=3amp;types=4amp;types=5"

request_url = 'https://www.moneysupermarket.com/bin/services/aggregation'
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'}
payload = {
'channelId': '55',
'enquiryId': '2e619c17-061a-4812-adad-40a9f9d8dcbc',
'limit': '20',
'offset': '0',
'sort': 'initialMonthlyPayment'}

data = requests.get(request_url, headers=headers, params = payload).json()

def flatten_json(y):
    out = {}
    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name   a   '_')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name   str(i)   '_')
                i  = 1
        else:
            out[name[:-1]] = x
    flatten(y)
    return out


results = pd.DataFrame()
for each in data['results']:
    flat = flatten_json(each)
    temp_df = pd.DataFrame([flat], columns = flat.keys())

    results = results.append(temp_df).reset_index(drop=True)
  

Вывод 2:

 print (results)
    apply_active  apply_desktop   ...    straplineLinkLabel  topTip
0           True           True   ...                  None    None
1           True           True   ...                  None    None
2           True           True   ...                  None    None
3           True           True   ...                  None    None
4           True           True   ...                  None    None
5           True           True   ...                  None    None
6           True           True   ...                  None    None
7           True           True   ...                  None    None
8           True           True   ...                  None    None
9           True           True   ...                  None    None
10          True           True   ...                  None    None
11          True           True   ...                  None    None
12          True           True   ...                  None    None
13          True           True   ...                  None    None
14          True           True   ...                  None    None
15          True           True   ...                  None    None
16          True           True   ...                  None    None
17          True           True   ...                  None    None
18          True           True   ...                  None    None
19          True           True   ...                  None    None

[20 rows x 131 columns]